denoland/deno · error · TypeError
First argument to 'respondWith' must be a Response…
Error message
First argument to 'respondWith' must be a Response constructed via the Response constructor in this realm
What it means
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).
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
Example fix
// before
const resp = new UndiciResponse("hi");
await e.respondWith(resp);
// after
const poly = new UndiciResponse("hi");
await e.respondWith(new Response(poly.body, poly)); Defensive patterns
Strategy: type-guard
Validate before calling
let resp = await maybePromise;
if (!(resp instanceof Response)) {
// rebuild with the ambient constructor so it carries the internal slot
resp = new Response((resp as Response | null)?.body ?? null, resp as ResponseInit);
}
await e.respondWith(resp); Type guard
const isRealmResponse = (v: unknown): v is Response => v instanceof Response; // same-realm check; polyfills fail this only if patched — prefer toInnerResponse semantics: rebuild when in doubt
Try / catch
try {
await e.respondWith(resp);
} catch (err) {
if (err instanceof TypeError && err.message.includes("this realm")) {
await e.respondWith(new Response(resp.body, resp)); // second attempt with global Response
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Return value from serve handler must be a Response…
- Invalid response
- Return value from onError handler must be a Response…
- Body is unusable
- First argument to 'respondWith' must be a Response or a…
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/3a79227e32fe4ffd.
Report an issue: GitHub.
Appendix: source
Thrown at ext/http/01_http.js:213
writeStreamRid,
) {
return async function respondWith(resp) {
try {
resp = await resp;
if (!(ObjectPrototypeIsPrototypeOf(ResponsePrototype, resp))) {
throw new TypeError(
"First argument to 'respondWith' must be a Response or a promise resolving to a Response",
);
}
// The Response prototype check above passes for Response-like objects
// that don't carry the internal slot (e.g. `Object.create(Response.prototype)`
// or a polyfilled/foreign-realm Response). Reject those here instead of
// crashing later on `innerResp.body`. Mirrors the Deno.serve guard
// added in #34416.
const innerResp = toInnerResponse(resp);
if (innerResp === undefined) {
throw new TypeError(
"First argument to 'respondWith' must be a Response constructed via the Response constructor in this realm",
);
}
// If response body length is known, it will be sent synchronously in a
// single op, in other case a "response body" resource will be created and
// we'll be streaming it.
/** @type {ReadableStream<Uint8Array> | Uint8Array | null} */
let respBody = null;
if (innerResp.body !== null) {
if (innerResp.body.unusable()) {
throw new TypeError("Body is unusable");
}
if (
ObjectPrototypeIsPrototypeOf(
ReadableStreamPrototype,
innerResp.body.streamOrStatic,
)View on GitHub (pinned to 9ad36f7a2c)