Skip to content

fix: handle undefined statusText in writeHead arguments#49

Open
mahmoodhamdi wants to merge 1 commit intojshttp:masterfrom
mahmoodhamdi:fix/writehead-undefined-statustext
Open

fix: handle undefined statusText in writeHead arguments#49
mahmoodhamdi wants to merge 1 commit intojshttp:masterfrom
mahmoodhamdi:fix/writehead-undefined-statustext

Conversation

@mahmoodhamdi
Copy link
Copy Markdown

Summary

Fixes argument parsing in setWriteHeadHeaders to correctly handle writeHead(statusCode, undefined, headers) — where the statusText is explicitly passed as undefined or null.

Problem

When res.writeHead(200, undefined, { 'X-Custom': 'value' }) is called through on-headers, the headers object at the third argument position is silently dropped.

Root cause: The argument parsing logic determines the header index based only on whether arguments[1] is a string:

var headerIndex = length > 1 && typeof arguments[1] === 'string'
    ? 2
    : 1

When arguments[1] is undefined, it's not a string, so headerIndex = 1. Then arguments[1] (which is undefined) is read as the headers, and the actual headers at arguments[2] are never accessed.

Without on-headers: Native Node.js writeHead(200, undefined, headers) works correctly.
With on-headers: Headers are silently dropped.

This was reported as expressjs/compression#254, where the compression middleware (which uses on-headers) caused headers to be lost when the Vercel AI SDK called writeHead(status, undefined, headers).

Fix

When there are more than 2 arguments, the headers are always at index 2 regardless of whether the second argument is a string, matching Node.js native writeHead behavior:

var headerIndex = length > 1 && typeof arguments[1] === 'string'
    ? 2
    : length > 2
      ? 2
      : 1

Testing

Added 2 new tests:

  • writeHead(status, undefined, obj) — headers are set correctly
  • writeHead(status, null, obj) — headers are set correctly

All 26 tests pass. Lint clean.

When writeHead is called with three arguments where the second
argument (statusText) is undefined or null, the headers object at
the third argument position was being ignored. This is because the
argument parsing only checked if the second argument was a string
to determine the header index, without considering that three
arguments always means the third is headers.

This caused headers set via writeHead(status, undefined, headers)
to be silently dropped, which affected downstream packages like
compression middleware (expressjs/compression#254).

The fix checks if there are more than two arguments, and if so,
always reads headers from the third position, matching Node.js
native writeHead behavior.
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.

1 participant