A response body is a consumable stream. Reuse the parsed value for ordinary logging and processing; create a clone before consumption only when a separate stream reader is actually required.
Reproduce the behavior safely
Run this self-contained fixture in an empty temporary directory, separate from your project. Shell examples create only named fixture files there. JavaScript examples use local values and send no network requests.
const assert = require('node:assert/strict');
(async () => {
const response = new Response('{"count":4}');
const duplicate = response.clone();
const data = await response.json();
assert.equal(response.bodyUsed, true);
await assert.rejects(() => response.text(), TypeError);
assert.equal(await duplicate.text(), '{"count":4}');
assert.equal(data.count, 4);
assert.throws(() => response.clone(), TypeError);
console.log('parsed once; early clone readable; late clone rejected');
})().catch(e => { console.error(e); process.exitCode = 1; });Observed local output
parsed once; early clone readable; late clone rejectedWhy the result changes
Calling json does more than convert text: it consumes the original body. Logging response.text and later returning response.json therefore asks two readers to consume one stream. Logging the already parsed data avoids that second read. A clone prepared before reading provides another branch, while a clone requested after use cannot repair the original stream.
Choose and verify the correction
Find every consumer in the request path, including debug logging, cache helpers and error handlers. Give one component ownership of parsing and pass its value onward. For a deliberate cache-and-return workflow, prepare the clone before handing either response to its consumer and await or otherwise own both tasks. In tests, create a new Response for each mocked request rather than returning the same consumed instance repeatedly.
Limits and next checks
The local fixture uses Node Response without network or service-worker execution. Cloning is not a free logging technique for large downloads: unread data on a slower branch can accumulate without a fixed limit. Prefer streaming with explicit ownership for large bodies. A body can also be locked by a reader, so bodyUsed alone is not a complete permission check. HTTP status policy remains a separate check.
Related: Fetch Resolves a 404 Response: Check HTTP Status Before Parsing Success Data.
Isolated fixture executed on macOS on November 10, 2026 (KST), with v26.5.0. The observed output verifies this example, not every application or runtime.