cloudflare / cloudflare/workers-sdk
wrangler dev exits when a queued request is abandoned by its client during startup/reload (ProxyWorker treats replay failure as fatal)
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.5k
- Avg merge
- 3d 8h
- Merged PRs (30d)
- 186
Description
### 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:
```jsonc
// wrangler.jsonc
{ "name": "repro-proxy-crash", "main": "worker.js", "compatibility_date": "2026-08-01" }
```
```js
// worker.js
export default { async fetch(req) { await req.text(); return new Response("ok"); } };
```
```sh
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.
Contributor guide
Research direction
Start with ProxyWorker.processQueue and the ProxyController error path described in the issue, then run the minimal wrangler dev reproduction with the queued POST request. Trace how a disconnected request fails during replay and verify that it is dropped without emitting a fatal ProxyWorker error, while genuine UserWorker failures remain fatal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100