Repository navigation
fix(request): forward duplex to the native request - #409
Open
Ahmad-Mosha wants to merge 1 commit into
Open
Ahmad-Mosha wants to merge 1 commit into
Ahmad-Mosha wants to merge 1 commit into
Conversation
Since undici 8.11 (Node.js 26.11), Request getters use private-field brand checks, so reading `duplex` on the lightweight request falls through to the native getter and throws ERR_INVALID_THIS. This breaks passing the request as RequestInit, e.g. `new Request(url, c.req.raw)` and `app.mount()`. Fixes honojs#408
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #408
On Node.js 26.11, passing the lightweight request as
RequestInitthrowsTypeError [ERR_INVALID_THIS]: Illegal invocation:Hono's own
app.mount()does the same thing (new Request(url, request)), so mounted apps return 500 on 26.11.Node.js 26.11.0 updated undici to 8.11.2, which includes nodejs/undici#5792 (released in 8.11.0). That change replaced the prototype-based
Requestbrand checks with private-field checks. The lightweight request inherits fromRequest.prototypebut has no private state. Any getter it doesn't define falls through to the native one, and that getter now throws.duplexis the onlyRequestInitmember that falls through. It is read in two places: by our constructor (options.duplex ??= 'half') and by undici'sRequestInitconversion.This adds
duplexto the getters forwarded to the cached native request, the same waykeepalivewas added in #148. The native getter always returns'half'. When the request is used asRequestInit,bodyis read beforeduplex, so the native request already exists and no extra work is done. A standaloneduplexread now builds the native request, like the other forwarded getters. Hono itself never reads it.Tests
duplexassertion to the standard Request compatibility test. Added two tests that pass a lightweight request as the init option: a GET, and a POST with a body. The GET test covers undici'sRequestInitconversion. The POST test coversduplex ??= 'half'in our constructor.mainwith Node.js 26.11.0 and 26.11.1 and pass with this change. On Node.js 26.10 and earlier they pass either way, because the old brand check accepted the lightweight request. This means the Node versions in the CI matrix can't catch a regression here.request.test.tsandserver.test.ts). They are unrelated to this issue.format,lint,typecheckandbuildare clean.duplexon the lightweight request throwsERR_INVALID_THIS, sonew Request(url, c.req.raw)fails #408 and anapp.mount()request against a packed build: 200 on Node 20, 22, 24, 26.10, 26.11.0 and 26.11.1.