# Fix Response body already used in middleware chain

## TL;DR

Read each response body exactly once. Call `response.clone()` before the first read when two consumers need the body, or read once and pass the parsed value to both. The root cause is simple: response bodies are single-use streams in workerd, so the second read always throws.

## Verbatim error

```text
workerd TypeError: Response body already used in middleware chain
```

## Steps

1. Find the two reads: search for `.json()`, `.text()`, or `.arrayBuffer()` called on the same response variable in the middleware and the handler. Expected: you identify both read sites.
2. In the middleware that reads first, clone before reading: `const copy = res.clone();` then read `copy` for logging and pass the original `res` onward. Expected: the clone call happens before any consumption.
3. Alternative when both consumers live in your code: read once into a const and hand the parsed value to both consumers. Expected: a single read, no clone needed.
4. If the reader is third-party middleware you cannot edit, wrap it: clone the response before it runs and restore from the clone after. Expected: downstream reads work.
5. Verify with a quick test: read twice from the same variable without a clone to confirm the error, then apply the fix and confirm both reads succeed. Expected: no "body already used" error.

## Use this when

- "Response body already used" appears in a workerd middleware chain
- A logging or metrics middleware that reads the body breaks the downstream handler
- Two plugins each try to parse the same fetch response

## Not for this skill when

- The error is about a request body already used (same shape on Request, mirror fix)
- TransformStream writer errors appear instead
- The body is consumed across a redirect (redirect handling, not double-read)

## Variant phrasings

- "body used already" response already read
- TypeError body stream locked workers
- cannot read response body twice cloudflare workers
- Response body has already been consumed

## Why it happens

Response bodies are ReadableStreams: reading locks and drains the stream. `clone()` tees the underlying stream so two readers can consume independently, but it must happen before the first byte is read. Middleware chains hit this constantly because each layer assumes it is the only reader.

## Edge cases

- `clone()` after a partial read throws, so clone eagerly at the top of the middleware.
- Cloning a large body doubles memory use; when both consumers are yours, prefer read-once-and-share.
- 204 and HEAD responses have no body, so body guards around them are unnecessary.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_fC2jekcsqDB2Bl-gDTzP_w
