{"record":{"id":"9eb19c85196fef12","repo":"denoland/deno","slug":"the-body-of-the-response-returned-from-the-serve-h","errorCode":null,"errorMessage":"The body of the Response returned from the serve handler has already been consumed","messagePattern":"The body of the Response returned from the serve handler has already been consumed","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/http/00_serve.ts","lineNumber":766,"sourceCode":"      // The Response prototype check above passes for Response-like objects\n      // (e.g. a subclass that skipped super(), or a Response from a different\n      // realm/polyfill). Those don't carry the internal slot we read from\n      // below, so reject them with a clear error instead of crashing later.\n      inner = getInnerResponse(response);\n      if (inner === undefined) {\n        throw new TypeError(\n          \"Return value from serve handler must be a Response constructed via the Response constructor in this realm\",\n        );\n      }\n\n      if (inner.type === \"error\") {\n        throw new TypeError(\n          \"Return value from serve handler must not be an error response (like Response.error())\",\n        );\n      }\n\n      if (responseBodyUsed(response)) {\n        throw new TypeError(\n          \"The body of the Response returned from the serve handler has already been consumed\",\n        );\n      }\n    } catch (error) {\n      try {\n        response = await onError(error);\n        if (!ObjectPrototypeIsPrototypeOf(ResponsePrototype, response)) {\n          throw new TypeError(\n            \"Return value from onError handler must be a response or a promise resolving to a response\",\n          );\n        }\n        inner = toInnerResponse(response);\n        if (inner === undefined) {\n          throw new TypeError(\n            \"Return value from onError handler must be a Response constructed via the Response constructor in this realm\",\n          );\n        }\n      } catch (error) {","sourceCodeStart":748,"sourceCodeEnd":784,"githubUrl":"https://github.com/denoland/deno/blob/abd22074e47c6a5cd14e9e4e84743f084aa5a575/ext/http/00_serve.ts#L748-L784","documentation":"Before serving, Deno.serve checks responseBodyUsed() and refuses a Response whose body stream has already been read or cancelled. Once a body is consumed it cannot be transmitted again, so the handler is returning an empty shell. The throw is routed to onError (500 by default).","triggerScenarios":"Reading the body for logging/inspection (`await response.text()`) and then returning the same object, returning a module-level cached Response instance that was already served once, or middleware that inspects the body without cloning.","commonSituations":"Response-logging middleware, a shared `const NOT_FOUND = new Response('Not Found', { status: 404 })` constant returned from many requests (the first serve consumes it), teeing bodies for audit trails without using clone().","solutions":["Replace cached Response constants with factories: `const notFound = () => new Response('Not Found', { status: 404 })`","Log via a clone: `await response.clone().text()`, return the original","If you must read the body, rebuild the Response: `const t = await r.text(); return new Response(t, r)`","Never hand the same Response object to two requests"],"exampleFix":"// before\nconst NOT_FOUND = new Response('Not Found', { status: 404 });\nDeno.serve(() => NOT_FOUND); // second request throws: body already consumed\n\n// after\nconst notFound = () => new Response('Not Found', { status: 404 });\nDeno.serve(() => notFound()); // fresh Response every request","handlingStrategy":"validation","validationCode":"// Validate before returning, and never reuse consumed Responses:\nif (response.bodyUsed) {\n  throw new Error('handler consumed the response body before returning it');\n}\nreturn response;","typeGuard":null,"tryCatchPattern":"// Logging without consuming: read the clone, return the original\nconst copy = response.clone();\nawait logBody(await copy.text());\nreturn response;","preventionTips":["Replace module-level cached Response constants with factory functions","Use clone() before any read meant for logging or auditing","If a body must be read then served, rebuild: new Response(await r.text(), r)"],"tags":["http","deno-serve","response-body","stream-consumed","caching"],"backgroundTag":"response-body-already-consumed","analyzedSha":"abd22074e47c6a5cd14e9e4e84743f084aa5a575","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}