denoland/deno · error · TypeError
Return value from serve handler must be a Response…
Error message
Return value from serve handler must be a Response constructed via the Response constructor in this realm
What it means
After the prototype check passes, Deno.serve reads the internal Deno response slot with getInnerResponse(). A value that looks like a Response (shares the prototype) but lacks that internal slot triggers this TypeError. Typical sources: a subclass that never called super(), or a Response object created by a different realm/polyfill (undici, node-fetch, a mock) that merely mimics the prototype chain.
Solutions
- Always call `super(init)` in Response subclasses before setting extra fields
- Do not import or return Response instances from undici/node-fetch/polyfills; use the global Response
- Re-wrap foreign instances: `return new Response(foreign.body, foreign)`
- In tests, build stubs with the real constructor instead of Object.create(Response.prototype)
Example fix
// before
class TeeShirt extends Response {
constructor(size) {
this.size = size; // no super() -> no internal slot
}
}
// after
class TeeShirt extends Response {
size;
constructor(size) {
super(`size=${size}`); // internal slot created
this.size = size;
}
} Defensive patterns
Strategy: validation
Validate before calling
// Re-wrap anything that might not carry the Deno internal slot:
let out = await callback(req, info);
if (!(out instanceof Response) || Object.getPrototypeOf(out) === null) {
out = new Response(out.body, out);
}
return out; Try / catch
// The internal slot is not observable from JS; rely on onError to convert this to a 500
Deno.serve({ handler, onError: () => new Response('Internal Server Error', { status: 500 }) }); Prevention
- Never import Response from undici/node-fetch or accept one from a dependency as a return value
- Always call super(init) in Response subclasses
- Build test doubles with the real constructor, not Object.create(Response.prototype)
When it happens
Trigger: `class MyResponse extends Response` whose constructor skips `super(...)` and only sets fields, returning a Response produced by an npm dependency that ships its own fetch implementation, or a stub object created with `Object.create(Response.prototype)` in tests.
Common situations: Custom Response subclasses adding metadata fields, framework middlewares that wrap or replace the Response with a polyfilled one, test doubles leaking into a running server, bundlers aliasing Response to a polyfill.
Related errors
- First argument to 'respondWith' must be a Response…
- Invalid response
- Return value from onError handler must be a Response…
- Both 'cert' and 'key' must be provided to enable HTTPS
- Cannot serve HTTP requests: either a `handler` or `options`…
AI-assisted analysis of denoland/deno@abd22074e4 (2026-08-20).
Data as JSON: /api/errors/e6b18143d9fb8144.
Report an issue: GitHub.
Appendix: source
Thrown at ext/http/00_serve.ts:754
request,
new ServeHandlerInfo(innerRequest),
);
}
// Throwing Error if the handler return value is not a Response class
if (!ObjectPrototypeIsPrototypeOf(ResponsePrototype, response)) {
throw new TypeError(
"Return value from serve handler must be a response or a promise resolving to a response",
);
}
// The Response prototype check above passes for Response-like objects
// (e.g. a subclass that skipped super(), or a Response from a different
// realm/polyfill). Those don't carry the internal slot we read from
// below, so reject them with a clear error instead of crashing later.
inner = getInnerResponse(response);
if (inner === undefined) {
throw new TypeError(
"Return value from serve handler must be a Response constructed via the Response constructor in this realm",
);
}
if (inner.type === "error") {
throw new TypeError(
"Return value from serve handler must not be an error response (like Response.error())",
);
}
if (responseBodyUsed(response)) {
throw new TypeError(
"The body of the Response returned from the serve handler has already been consumed",
);
}
} catch (error) {
try {
response = await onError(error);View on GitHub (pinned to abd22074e4)