{"record":{"id":"3a79227e32fe4ffd","repo":"denoland/deno","slug":"first-argument-to-respondwith-must-be-a-response-3a7922","errorCode":null,"errorMessage":"First argument to 'respondWith' must be a Response constructed via the Response constructor in this realm","messagePattern":"First argument to 'respondWith' must be a Response constructed via the Response constructor in this realm","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/http/01_http.js","lineNumber":213,"sourceCode":"  writeStreamRid,\n) {\n  return async function respondWith(resp) {\n    try {\n      resp = await resp;\n      if (!(ObjectPrototypeIsPrototypeOf(ResponsePrototype, resp))) {\n        throw new TypeError(\n          \"First argument to 'respondWith' must be a Response or a promise resolving to a Response\",\n        );\n      }\n\n      // The Response prototype check above passes for Response-like objects\n      // that don't carry the internal slot (e.g. `Object.create(Response.prototype)`\n      // or a polyfilled/foreign-realm Response). Reject those here instead of\n      // crashing later on `innerResp.body`. Mirrors the Deno.serve guard\n      // added in #34416.\n      const innerResp = toInnerResponse(resp);\n      if (innerResp === undefined) {\n        throw new TypeError(\n          \"First argument to 'respondWith' must be a Response constructed via the Response constructor in this realm\",\n        );\n      }\n\n      // If response body length is known, it will be sent synchronously in a\n      // single op, in other case a \"response body\" resource will be created and\n      // we'll be streaming it.\n      /** @type {ReadableStream<Uint8Array> | Uint8Array | null} */\n      let respBody = null;\n      if (innerResp.body !== null) {\n        if (innerResp.body.unusable()) {\n          throw new TypeError(\"Body is unusable\");\n        }\n        if (\n          ObjectPrototypeIsPrototypeOf(\n            ReadableStreamPrototype,\n            innerResp.body.streamOrStatic,\n          )","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/http/01_http.js#L195-L231","documentation":"A stricter follow-up check after the prototype test in `respondWith`: `toInnerResponse(resp)` must find Deno's internal response slot. Objects that merely imitate a Response — `Object.create(Response.prototype)`, a polyfilled Response (undici/node-fetch/cross-fetch), or a Response created in another realm — pass the prototype check but carry no internal slot, and would crash later when the internal body is read. Deno rejects them up front (mirrors the `Deno.serve` guard from PR #34416).","triggerScenarios":"Passing `new undici.Response(...)` or a node-fetch Response to `respondWith`; handing over `Object.create(Response.prototype)` test doubles; Responses crossing worker/vm realm boundaries.","commonSituations":"Libraries that bundle their own fetch implementation (SSR frameworks, SDKs, isomorphic-fetch/cross-fetch); mocking Response in tests; code that runs the handler inside a separate worker or vm context.","solutions":["Rebuild the response with the ambient global constructor: `new Response(poly.body, poly)`","Configure imports/bundlers so Deno's global `Response` is used instead of a polyfill","In tests, stub with real `Response` instances rather than prototype fakes"],"exampleFix":"// before\nconst resp = new UndiciResponse(\"hi\");\nawait e.respondWith(resp);\n\n// after\nconst poly = new UndiciResponse(\"hi\");\nawait e.respondWith(new Response(poly.body, poly));","handlingStrategy":"type-guard","validationCode":"let resp = await maybePromise;\nif (!(resp instanceof Response)) {\n  // rebuild with the ambient constructor so it carries the internal slot\n  resp = new Response((resp as Response | null)?.body ?? null, resp as ResponseInit);\n}\nawait e.respondWith(resp);","typeGuard":"const isRealmResponse = (v: unknown): v is Response =>\n  v instanceof Response; // same-realm check; polyfills fail this only if patched — prefer toInnerResponse semantics: rebuild when in doubt","tryCatchPattern":"try {\n  await e.respondWith(resp);\n} catch (err) {\n  if (err instanceof TypeError && err.message.includes(\"this realm\")) {\n    await e.respondWith(new Response(resp.body, resp)); // second attempt with global Response\n  } else throw err;\n}","preventionTips":["Do not import fetch polyfills (cross-fetch, node-fetch, undici Response) in Deno code paths","If a library hands you its own Response, rebuild it with the global `Response` before responding","In tests, use real Response instances instead of prototype spoofing"],"tags":["http","respondwith","response","polyfill","cross-realm"],"backgroundTag":"cross-realm-response","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}