cloudflare / cloudflare/workers-sdk
miniflare 5.20260911.0-alpha: Response.clone() on a dispatchFetch response (DO-forwarded stream) throws "Body has already been consumed" although bodyUsed is false
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.5k
- Avg merge
- 3d 8h
- Merged PRs (30d)
- 187
Description
### What versions & operating system are you using?
- miniflare `5.20260911.0-alpha` (workerd `1.20260911.1`), wrangler `4.131.1` — **fails**
- miniflare `5.20260907.0-alpha` (workerd `1.20260907.1`), wrangler `4.129.1` — **passes** (control, same Worker and test)
- Node `24.18.0`, macOS 25.5 (arm64)
### Please provide a link to a minimal reproduction
No public repository yet; the reproduction shape is small and described below (happy to extract it into a standalone repo if useful).
### Describe the Bug
Since miniflare `5.20260911.0-alpha`, calling `response.clone()` on a `Response` returned by `mf.dispatchFetch()` throws `TypeError: Response.clone: Body has already been consumed`, even though immediately before the clone the response reports `bodyUsed === false`, `body !== null`, `status === 201`.
Setup: the Worker forwards `/api/...` requests to a Durable Object with `stub.fetch(new Request(request, { headers }))` and returns `new Response(result.body, result)` (re-wrapped to add headers); the DO answers with `Response.json({...}, { status: 201 })`.
Observed on the same run, same Worker, same forwarding path:
- 32 concurrent `POST` requests with a ~600 KB **JSON** body (`content-type: application/json`) → all `201`, `response.clone().text()` works.
- 32 concurrent `POST` requests with a 600 KB **binary** body (`content-type: audio/webm`, `content-length: 600000`, `body: new Uint8Array(600000)`) → all `201`, `response.bodyUsed === false`, `response.body !== null`, response `content-type: application/json` — and `await response.clone().text()` throws for each.
So the response side is identical (a DO `Response.json` forwarded as a stream); the difference is the request body type/size. On `5.20260907.0-alpha` both bursts pass.
Expected: `clone()` succeeds while `bodyUsed` is `false`, as on `5.20260907.0-alpha`.
### Please provide any relevant error logs
```
TypeError: Response.clone: Body has already been consumed.
at webidl.errors.exception (node_modules/undici/lib/web/webidl/index.js:35:10)
at _Response.clone (node_modules/undici/lib/web/fetch/response.js:235:27)
at _Response.clone (node_modules/miniflare/dist/src/index.js:64074:28)
at : `await response.clone().text()` after `mf.dispatchFetch(...)`
```
Probe output on the same responses just before the clone (bumped tree):
```
media statuses=201 bodyUsed=false hasBody=true ctype=application/json
```
Contributor guide
Research direction
Start by reproducing the regression through miniflare's mf.dispatchFetch() with the Durable Object forwarding path, comparing the passing and failing alpha versions. Exercise the 32-request JSON and binary-body cases and inspect the returned Response before clone(); done means response.clone().text() succeeds when bodyUsed is false, matching 5.20260907.0-alpha.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100