{"record":{"id":"958fd14b95b7b535","repo":"denoland/deno","slug":"invalid-response","errorCode":null,"errorMessage":"Invalid response","messagePattern":"Invalid response","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/http/00_serve.ts","lineNumber":670,"sourceCode":"  if (typeof body === \"string\") {\n    innerRequest?.close();\n    if (headers?.length > 0) {\n      op_http_set_response_body_text_with_headers(\n        req,\n        body,\n        status,\n        headers,\n      );\n    } else {\n      op_http_set_response_body_text(req, body, status);\n    }\n    return;\n  }\n\n  // At this point in the response it needs to be a stream\n  if (!ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, stream)) {\n    innerRequest?.close();\n    throw new TypeError(\"Invalid response\");\n  }\n  setResponseHeaders(req, headers);\n  const resourceBacking = getReadableStreamResourceBacking(stream);\n  let rid, autoClose;\n  if (resourceBacking) {\n    rid = resourceBacking.rid;\n    autoClose = resourceBacking.autoClose;\n  } else {\n    // The response headers/status have already been committed by the time the\n    // body stream starts producing chunks, so an error thrown while draining\n    // the stream (e.g. inside a `TransformStream` transformer) can no longer\n    // change the response. Report it through the server's error handler so it\n    // is not silently swallowed and a stack trace implicating the faulty\n    // callback is surfaced. See https://github.com/denoland/deno/issues/19867.\n    rid = resourceForReadableStream(stream, undefined, onError);\n    autoClose = true;\n  }\n  PromisePrototypeThen(","sourceCodeStart":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/denoland/deno/blob/abd22074e47c6a5cd14e9e4e84743f084aa5a575/ext/http/00_serve.ts#L652-L688","documentation":"Thrown by fastSyncResponseOrStream when a handler's Response body reached the final dispatch branch but its internal streamOrStatic value is not a ReadableStream. The function already handled null/undefined, static strings, and Uint8Array bodies, so hitting this check means the Response object did not come from a genuine in-realm Response constructor (mock, polyfill, or cross-realm instance) or its internal InnerBody was abnormal. The request is closed and the error is routed through onError, so clients see a 500 if it is unhandled.","triggerScenarios":"Returning a Response created by another package's Response class (undici, node-fetch, a test double), returning an object that only duck-types Response after prototype checks were bypassed, or a bundler/polyfill replacing globalThis.Response before Deno.serve inspects the returned value.","commonSituations":"SSR/framework code bundled with a fetch polyfill for Node compatibility, unit-test Response mocks accidentally used in a live server, monorepos where a shared package exports its own Response implementation.","solutions":["Return only Responses built by the runtime's global Response constructor","Re-wrap foreign Responses at the boundary: `return new Response(foreign.body, foreign)`","Remove packages that overwrite globalThis.Response, or configure the bundler to not polyfill fetch in Deno builds","Build bodies only from null, string, Uint8Array, Blob, or ReadableStream"],"exampleFix":"// before\nimport { Response as UndiciResponse } from 'undici';\nDeno.serve(() => fetchViaUndici()); // returns undici Response -> Invalid response\n\n// after\nDeno.serve(async () => {\n  const foreign = await fetchViaUndici();\n  return new Response(foreign.body, foreign); // native Response, stream body passes\n});","handlingStrategy":"validation","validationCode":"// Before returning anything that might be foreign, verify the body type:\nconst body = candidate.body;\nif (\n  body !== null &&\n  typeof body !== 'string' &&\n  !(body instanceof Uint8Array) &&\n  !(body instanceof Blob) &&\n  !(body instanceof ReadableStream)\n) {\n  throw new Error(`Unsupported response body: ${Object.prototype.toString.call(body)}`);\n}\nreturn candidate instanceof Response ? candidate : new Response(body, candidate);","typeGuard":"const isServableBody = (b: unknown): b is BodyInit =>\n  b === null ||\n  typeof b === 'string' ||\n  b instanceof Uint8Array ||\n  b instanceof Blob ||\n  b instanceof ReadableStream;","tryCatchPattern":null,"preventionTips":["Only return Response objects created by the global Response constructor","Never let bundles or packages replace globalThis.Response in a Deno server build","Re-wrap Responses crossing package boundaries with new Response(foreign.body, foreign)"],"tags":["http","deno-serve","response-body","polyfill","cross-realm"],"backgroundTag":"invalid-response-body-type","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"}