denoland/deno · error · TypeError
First argument to 'respondWith' must be a Response construct
Error message
First argument to 'respondWith' must be a Response constructed via the Response constructor in this realm
What it means
A second, stricter guard after the prototype check: toInnerResponse(resp) must return an inner response, i.e. the object must carry Deno's internal Response slot, which only objects built by this realm's Response constructor have. Objects that fake it (Object.create(Response.prototype), Response subclasses instantiated in another realm/worker, or polyfilled Responses) pass the prototype test but lack the internal slot and are rejected here instead of crashing on innerResp.body.
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 89f33cbef2)
Solutions
- Construct the response in the same realm with the real constructor: new Response(body, init).
- When receiving a value from another realm, rebuild it: httpConn.respondWith(new Response(await foreignResp.body, foreignResp)).
- Remove polyfills/shims for Response from the serving path (don't polyfill built-ins when running under Deno).
Example fix
// before
const fake = Object.create(Response.prototype);
fake.status = 200;
httpConn.respondWith(fake);
// after
httpConn.respondWith(new Response("ok")); Defensive patterns
Strategy: validation
Validate before calling
function isRealmResponse(v: unknown): boolean {
if (!(v instanceof Response)) return false;
try { return Object.getOwnPropertySymbols(v).length > 0 || new Response(v.body, v).body !== undefined || true; } catch { return false; }
} Type guard
function isRealResponse(v: unknown): v is Response { try { return v instanceof Response && !(Symbol.for("deno.inner") in (v as object) && (v as any)[Symbol.for("deno.inner")] === undefined); } catch { return false; } } Try / catch
try { await httpConn.respondWith(resp); } catch (e) { if (e instanceof TypeError && e.message.includes("in this realm")) { await httpConn.respondWith(new Response(null, { status: resp.status ?? 200, headers: resp.headers })); return; } throw e; } Prevention
- Construct responses with the global Response of the running realm - never Object.create(Response.prototype).
- Rebuild cross-realm/polyfilled responses: new Response(foreign.body, foreign).
- Don't ship Response polyfills under Deno; map imports so 'response' resolves to the builtin.
When it happens
Trigger: Object.create(Response.prototype) passed to respondWith; a Response created inside a Worker or vm-like realm and shipped to the main thread; a Response polyfill whose instances share Response.prototype but never went through the constructor; cloned structurally via property copying.
Common situations: Cross-realm code (node compat shims, sandboxed evaluators, import maps pulling a fetch polyfill); libraries that wrap/subclass Response from a different Deno instance; defensive Object.create tricks to avoid constructor validation.
Related errors
- First argument to 'respondWith' must be a Response or a prom
- Return value from serve handler must be a response or a prom
- Return value from serve handler must be a Response construct
- Return value from serve handler must not be an error respons
- The body of the Response returned from the serve handler has
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/3a79227e32fe4ffd.
Report an issue: GitHub.