[wrangler] fix: patch undici to prevent fetch() throwing on 401 responses with a request body#13058
Conversation
… request body isTraversableNavigable() in undici 7.24.4 unconditionally returns true, causing the 401 credential-retry block in httpNetworkOrCacheFetch to always execute in Node.js. When the request body source is null (e.g. when passing a Request object as fetch init), this throws 'expected non-null body source'. Tracked upstream in nodejs/undici#4910. Workaround: apply a pnpm patch that returns false from isTraversableNavigable(), preventing the retry block from ever entering in Node.js where there is no browser UI to prompt for credentials. Fixes: #12967
|
Codeowners approval required for this PR:
Show detailed file reviewers |
|
✅ All changesets look good |
|
I've reviewed the full diff. Here's my analysis:
No logic bugs, no security issues, no backward compatibility concerns. This is a straightforward, well-documented workaround for an upstream bug. LGTM |
create-cloudflare
@cloudflare/kv-asset-handler
miniflare
@cloudflare/pages-shared
@cloudflare/unenv-preset
@cloudflare/vite-plugin
@cloudflare/vitest-pool-workers
@cloudflare/workers-editor-shared
wrangler
commit: |
|
I just hit this on wrangler 4.77. Will this on the next version release? |
|
👍 I've tried the preview build on the reproduction repo. |
Just a note, 4.78 doesn't fix this in when testing with The fix is present in bundled wrangler-dist/cli.js, but the local Miniflare path is resolving a separate unpatched external undici. So miniflare is unpatched even if wrangler/cli.js is patched. |
|
Yeah I was just thinking about that yesterday. I'll work on a better fix. |
Fixes #12967.
Unstable_DevWorker.fetch()(and any other use of undici'sfetchin wrangler) throwsTypeError: fetch failedwith causeexpected non-null body sourcewhenever a request with a body receives a401response.Root cause
isTraversableNavigable()in undici 7.24.4 unconditionally returnstrue— a stub left in place from nodejs/undici#4747. This causes the 401 credential-retry block inhttpNetworkOrCacheFetchto always execute, even in Node.js where there is no browser UI to prompt users for credentials. When the request body'ssourceisnull(which happens when aRequestobject is passed as theinitargument tofetch()), the retry block immediately throwsmakeNetworkError('expected non-null body source').The earlier fix in nodejs/undici#4761 (v7.19.1) added a
return responseto prevent an infinite retry loop, but that code is unreachable in this case — thebody.source == nullguard fires first.This is tracked upstream as nodejs/undici#4910 with no fix in progress yet.
Fix
Apply a
pnpm patchto undici that changesisTraversableNavigable()to returnfalse. In Node.js there is no traversable navigable (no browser tab), so the 401-retry block should never be entered. This is a one-line change that exactly mirrors the correct upstream fix and can be removed once a patched undici version is released.cli.jsnow hasisTraversableNavigablereturningfalse)