Skip to content

wrangler dev exits when a queued request is abandoned by its client during startup/reload (ProxyWorker treats replay failure as fatal) #15447

Description

@LiyanChen-X

Which Cloudflare product(s) does this pertain to?

Wrangler

What versions are you using?

wrangler 4.125.0 and 4.127.1 (both reproduce), Node 24.19.0, macOS 15 (arm64)

What operating system and version are you using?

macOS 15.6 (Darwin 25.6.0), also observed with Containers/Durable Objects dev

Please provide a link to a minimal reproduction

Minimal, no Containers required:

// wrangler.jsonc
{ "name": "repro-proxy-crash", "main": "worker.js", "compatibility_date": "2026-08-01" }
// worker.js
export default { async fetch(req) { await req.text(); return new Response("ok"); } };
head -c 2000000 /dev/urandom > body.bin
npx wrangler@4.127.1 dev --port 8799 &
# wait for "Ready on http://localhost:8799"
echo "// touch" >> worker.js        # triggers a reload -> ProxyWorker pauses and queues requests
sleep 0.15
curl -m 0.4 -X POST --data-binary @body.bin http://127.0.0.1:8799/upload   # client gives up while queued

Output (one round is enough):

⎔ Reloading local server...
⎔ Local server updated and ready
✘ [ERROR]
If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose
[wrangler:error] Error: Network connection lost.

wrangler dev exits with code 1. In the debug log the ProxyController error is:

Error in ProxyController: Error inside ProxyWorker
  cause: TypeError: Can't read from request stream because client disconnected.

Please provide the steps to reproduce and describe the observed vs. expected behaviour

Observed: While the UserWorker is starting (first boot, or a reload after a file change — with Containers this window is 20–40 s while the image builds), ProxyWorker queues incoming requests (requestQueue) and replays them on play. If the client abandoned a queued request with a body before replay (any caller with a request timeout shorter than the startup window), new Request(request, …) / the upstream fetch fails while reading the body. In processQueue's catch, because isSameUserWorkerOrigin(...) is true, the error is sent to the ProxyController as { type: "error" }, which calls emitErrorEvent("Error inside ProxyWorker", …) and the whole dev session exits. Every other process in a Turbo dev task group is torn down with it.

Expected: A request whose client already disconnected has nobody waiting for a response; it should be dropped (reject its deferred, debug-log it) without treating it as a ProxyWorker failure. Only genuine failures to reach the current UserWorker should be fatal.

How we hit it in practice: a backend service polls the Worker (POST with a JSON body, 5 s request deadline) every 30 s. During wrangler dev startup the container image build takes ~30 s, the poll gets queued, the deadline aborts it, and the moment the image is ready wrangler dev dies. Opening the app page (which triggers the same call) reproduces it on demand.

I have a small fix ready (drop abandoned requests instead of reporting them as fatal) and will open a draft PR referencing this issue.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions