Skip to content

fix: send 0 and false request bodies as JSON - #646

Open
rhelling wants to merge 1 commit into
unjs:mainfrom
rhelling:fix/falsy-json-body
Open

rhelling wants to merge 1 commit into
unjs:mainfrom
rhelling:fix/falsy-json-body

Conversation

@rhelling

@rhelling rhelling commented Nov 4, 2026 •

Copy link
Copy Markdown

resolves #645

A request body of 0 or false was sent as text/plain, while 1 and true were sent as JSON: the body was only prepared when truthy (if (context.options.body && isPayloadMethod(...))), so 0 and false skipped the serialization and the content-type header and reached fetch() as they are.

The guard now checks for "no body" instead of truthiness: only undefined and null mean no body, as for fetch() itself. An empty string is deliberately left to fetch() as before, since there is nothing to serialize and an empty application/json body would not be a JSON document. isJSONSerializable() already accepted numbers and booleans, so nothing else changes.

Tests: 0 and false arrive as application/json with the body 0 / false; undefined and null send no body and no content type. The first test fails without the fix.

Reproduction: https://github.com/rhelling/ofetch-request-body-repo — 0 of 8 cases fail against a build of this branch, 2 of 8 against 1.5.1 and 2.0.0-alpha.3.

Summary by CodeRabbit

  • Bug Fixes
    • POST requests now correctly send 0 and false values as JSON bodies. undefined and null continue to produce empty bodies without a content-type header.

The body was only prepared when truthy, so 0 and false skipped the JSON
serialization and the content-type header, and fetch sent them as
text/plain. Only undefined and null mean "no body" now; an empty string
is still left to fetch, as there is nothing to serialize.
@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

$fetchRaw now processes payload-method bodies unless they are undefined, null, or the empty string. Tests verify that 0 and false are sent as JSON and that undefined and null produce no body.

Changes: Request body serialization

Layer / File(s) Summary
Payload body check and regression tests
src/fetch.ts, test/index.test.ts
The payload-method body check excludes undefined, null, and the empty string. Tests verify that 0 and false are serialized as JSON with the application/json content type, while undefined and null produce an empty body without a content-type header.

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: Minimal · up to 6d422

The change correctly supports falsy JSON request bodies and preserves no-body handling for undefined and null.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: serializing 0 and false request bodies as JSON.
Linked Issues check Passed Issue #645 requires 0 and false request bodies to use JSON with content-type: application/json, and requires undefined and null to remain no body. In src/fetch.ts, body preparation now exc…
Out of Scope Changes check Passed The reviewed changes are limited to the request-body preparation condition in src/fetch.ts and tests for the cases in issue #645. The tests directly cover the requested behavior. No unrelated change…
Full details: Linked Issues check

Explanation

Issue #645 requires 0 and false request bodies to use JSON with content-type: application/json, and requires undefined and null to remain no body. In src/fetch.ts, body preparation now excludes only undefined, null, and the empty string before the existing JSON serialization path. In test/index.test.ts, tests verify JSON bodies and the content type for 0 and false, and verify an empty body without content-type for undefined and null.

Full details: Out of Scope Changes check

Explanation

The reviewed changes are limited to the request-body preparation condition in src/fetch.ts and tests for the cases in issue #645. The tests directly cover the requested behavior. No unrelated change is evident.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 2 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 500d61a0-90a6-4d39-8665-7cdc6eaeab1d
Commits

Reviewing files that changed from the base of the PR and between 1dbc37f and 6d422b9.

Files selected for processing: 2
  • src/fetch.ts
  • test/index.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

@agammann agammann left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I traced the new guard through the JSON serialization path: 0 and false now reach isJSONSerializable and get the JSON content type, while undefined, null, and the deliberately excluded empty string keep their existing empty-body behavior. The echo tests check both the bytes sent and the header, so this covers the regression at the public $fetch boundary. I did not run tests locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Falsy request bodies are sent as text/plain instead of application/json

2 participants