denoland/deno · error · TypeError
First argument to 'respondWith' must be a Response or a prom
Error message
First argument to 'respondWith' must be a Response or a promise resolving to a Response
What it means
Thrown inside the async respondWith closure created per-request by Deno.serveHttp(httpConn). It awaits the value the handler passed to httpConn.respondWith() and then requires it to have Response.prototype in its prototype chain. Anything that does not resolve to a real Response instance (plain object, string, number, undefined, a Response-like duck-typed object) triggers this TypeError.
Source
Thrown at ext/http/01_http.js:201
const reqEvt = await httpConn.nextRequest();
// Change with caution, current form avoids a v8 deopt
return { value: reqEvt ?? undefined, done: reqEvt === null };
},
};
}
}
function createRespondWith(
httpConn,
request,
readStreamRid,
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 andView on GitHub (pinned to 89f33cbef2)
Solutions
- Always resolve to a real Response: httpConn.respondWith(new Response(body, { status, headers })).
- Audit every code path in the handler passed to respondWith so each returns a Response (add a fallback `return new Response('error', { status: 500 })`).
- If you have a plain object, construct a Response from it instead of passing it directly.
- Use Deno.serve(handler) instead of the low-level serveHttp loop unless you need raw connection control.
Example fix
// before
httpConn.respondWith({ status: 200, body: "hello" });
// after
httpConn.respondWith(new Response("hello", { status: 200 })); Defensive patterns
Strategy: type-guard
Type guard
async function isResponse(v: unknown): Promise<boolean> { return Object.prototype.isPrototypeOf.call(Response.prototype, await v); } Try / catch
try { await httpConn.respondWith(handlerResult); } catch (e) { if (e instanceof TypeError && /respondWith/.test(e.message)) { await httpConn.respondWith(new Response("bad handler", { status: 500 })); return; } throw e; } Prevention
- Type handler return values as Response | Promise<Response> so the compiler enforces it.
- Add an exhaustiveness fallback `return new Response('unreachable', { status: 500 })` to async branches.
- Prefer Deno.serve(handler) over manual serveHttp loops unless you need raw connections.
When it happens
Trigger: Calling httpConn.respondWith(new Request(...)) instead of a Response; returning/resolving to a plain object { status: 200, body: 'x' }; passing a string promise; passing undefined because an if/else branch forgot a return; passing a fetch-style WHATWG Response polyfill.
Common situations: Hand-rolled Deno.serveHttp loops migrated from service-worker style code; async handlers where one branch returns nothing; JSON helpers that return parsed bodies rather than Response objects; third-party Response polyfills leaking into the handler.
Related errors
- First argument to 'respondWith' must be a Response construct
- 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/43b40eec402e4d12.
Report an issue: GitHub.