Skip to content

fix: empty-body status codes send body when using string status names#1833

Open
alexkahndev wants to merge 2 commits intoelysiajs:mainfrom
alexkahndev:fix/empty-body-status-codes
Open

fix: empty-body status codes send body when using string status names#1833
alexkahndev wants to merge 2 commits intoelysiajs:mainfrom
alexkahndev:fix/empty-body-status-codes

Conversation

@alexkahndev
Copy link
Copy Markdown

@alexkahndev alexkahndev commented Mar 31, 2026

Summary

  • ElysiaCustomStatusResponse constructor checks code in emptyHttpStatus, but when using string status names like status('No Content'), code is 'No Content' while emptyHttpStatus keys are numeric (204). The lookup always fails, so this.response is never cleared — resulting in a response body being sent with 204/205/304/etc.
  • Fixed by checking this.code in emptyHttpStatus instead, since this.code is already resolved to the numeric status via StatusMap.
  • Also changed mapResponse's case undefined to use new Response(null, set) instead of new Response('', set) in both the bun and web-standard adapters, since HTTP spec requires no body for these status codes and an empty string still produces a ReadableStream body.

Test plan

  • Added test/response/no-content-status.test.ts with 3 tests covering 204 (no args), 204 (with message arg), and 205
  • Verified all 3 tests fail before the fix and pass after
  • Full test suite passes (1528/1528)

Summary by CodeRabbit

  • Bug Fixes

    • Consistent handling of empty/falsy responses so no-content statuses (204, 205) return null bodies across environments.
    • Ensure status-based response clearing uses the resolved HTTP status when deciding to omit a body.
  • Tests

    • Added tests verifying 204/205 responses have null bodies and correct statuses.

… using string status names

ElysiaCustomStatusResponse constructor checked `code in emptyHttpStatus` but `code` is the
string name (e.g. 'No Content') while emptyHttpStatus keys are numeric (204). Changed to
check `this.code` which is already resolved to the numeric status via StatusMap.

Also changed mapResponse undefined case to use `new Response(null, set)` instead of
`new Response('', set)` as HTTP spec requires no body for 204/205 responses.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 91a775fd-185e-4e22-aba0-5ae571df3d5f

📥 Commits

Reviewing files that changed from the base of the PR and between 0aa99c0 and ea98613.

📒 Files selected for processing (3)
  • src/adapter/bun/handler.ts
  • src/adapter/web-standard/handler.ts
  • test/response/no-content-status.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/adapter/bun/handler.ts
  • test/response/no-content-status.test.ts

Walkthrough

Updated response mapping in Bun and Web handlers to return new Response(null, ...) when the original response is falsy and the constructor name is undefined. Adjusted ElysiaCustomStatusResponse to check the normalized status code (this.code) before clearing the response. Added tests validating 204/205 bodies are null.

Changes

Cohort / File(s) Summary
Response Adapter Handlers
src/adapter/bun/handler.ts, src/adapter/web-standard/handler.ts
Changed fallback response body from empty string ('') to null when response is falsy and the constructor name branch is undefined in mapResponse/mapEarlyResponse/mapCompactResponse.
Error Status Handling
src/error.ts
Switched guard to check the normalized status code (this.code) rather than the raw code parameter when deciding to clear response for empty-status codes.
Status Code Tests
test/response/no-content-status.test.ts
Added tests asserting endpoints returning 204/205 produce responses with status 204/205 and response.body === null.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • patch: 1.4.22 #1657 — Modifies the same response-mapping code paths (mapResponse / mapEarlyResponse / mapCompactResponse), likely related to this change.

Poem

null not empty, tidy and neat〜♡ (¬‿¬)
204s sleep with no treat〜♡ (⌒‿⌒)
responses trimmed, not a single stray bit〜♡
tests clap, the silence is lit〜♡ (`∀´)

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: empty-body HTTP status codes now correctly send no body when using string status names, which is the core issue addressed across the adapter handlers and error class.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
test/response/no-content-status.test.ts (1)

5-43: Heee~ the tests look nice, buuut~ ( ̄∇ ̄)

Your describe block is called '204 No Content' but you snuck in a test for 205 Reset Content too~! That's a bit misleading, don't you think, silly~? ♡

Also, emptyHttpStatus includes other codes like 304 Not Modified - maybe you could add coverage for that too someday~? But I gueeess this is enough for now... (´-ω-`)

♻️ Suggestion for cleaner test organization~
-describe('204 No Content', () => {
+describe('Empty Body Status Codes', () => {
 	it('should return null body for status No Content', async () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/response/no-content-status.test.ts` around lines 5 - 43, The describe
block label "'204 No Content'" is misleading because it also contains a test for
the 205 "Reset Content" case (the test that defines a POST '/reset' route and
calls status('Reset Content')); rename the describe to something generic like
"'Empty HTTP statuses'" or split the 205 test into its own describe (e.g., "'205
Reset Content'") so the suite name matches its contents; update the describe
string that wraps the tests accordingly to reflect either multiple empty
statuses or move the test with status('Reset Content') into a separate describe
block.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/adapter/bun/handler.ts`:
- Line 59: The two functions mapEarlyResponse and mapCompactResponse currently
return new Response('') for falsy responses; make them consistent with
mapResponse by returning new Response(null, set as any) instead (i.e., check for
!response and return new Response(null, set as any)). Update the falsy-response
branches in mapEarlyResponse and mapCompactResponse to match the same return
pattern used by mapResponse.

In `@src/adapter/web-standard/handler.ts`:
- Line 93: Update the two remaining spots that still create an empty-body
Response with a string: in mapEarlyResponse and mapCompactResponse replace any
occurrences of new Response('') (or returning a falsy response as an empty
string body) with the same HTTP-spec-compliant pattern used at the earlier
change—return new Response(null, set as any) (or construct the Response with
null as the body and the appropriate init/options) and ensure any type
assertions match the existing handler pattern so the compiler is satisfied.

---

Nitpick comments:
In `@test/response/no-content-status.test.ts`:
- Around line 5-43: The describe block label "'204 No Content'" is misleading
because it also contains a test for the 205 "Reset Content" case (the test that
defines a POST '/reset' route and calls status('Reset Content')); rename the
describe to something generic like "'Empty HTTP statuses'" or split the 205 test
into its own describe (e.g., "'205 Reset Content'") so the suite name matches
its contents; update the describe string that wraps the tests accordingly to
reflect either multiple empty statuses or move the test with status('Reset
Content') into a separate describe block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 72d9b26b-145b-4700-8e70-739dbabe7db8

📥 Commits

Reviewing files that changed from the base of the PR and between 56310be and 0aa99c0.

📒 Files selected for processing (4)
  • src/adapter/bun/handler.ts
  • src/adapter/web-standard/handler.ts
  • src/error.ts
  • test/response/no-content-status.test.ts

Comment thread src/adapter/bun/handler.ts
Comment thread src/adapter/web-standard/handler.ts
…sistency

Updated all remaining `new Response('')` falsy-response branches to
`new Response(null)` in both bun and web-standard adapters, matching
the pattern already used in mapResponse.

Renamed test describe block to 'Empty HTTP statuses' to reflect
coverage of both 204 and 205.
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.

2 participants