denoland/deno · error · TypeError

Invalid response

Error message

Invalid response

What it means

Thrown by fastSyncResponseOrStream when a handler's Response body reached the final dispatch branch but its internal streamOrStatic value is not a ReadableStream. The function already handled null/undefined, static strings, and Uint8Array bodies, so hitting this check means the Response object did not come from a genuine in-realm Response constructor (mock, polyfill, or cross-realm instance) or its internal InnerBody was abnormal. The request is closed and the error is routed through onError, so clients see a 500 if it is unhandled.

Solutions

  1. Return only Responses built by the runtime's global Response constructor
  2. Re-wrap foreign Responses at the boundary: `return new Response(foreign.body, foreign)`
  3. Remove packages that overwrite globalThis.Response, or configure the bundler to not polyfill fetch in Deno builds
  4. Build bodies only from null, string, Uint8Array, Blob, or ReadableStream

Example fix

// before
import { Response as UndiciResponse } from 'undici';
Deno.serve(() => fetchViaUndici()); // returns undici Response -> Invalid response

// after
Deno.serve(async () => {
  const foreign = await fetchViaUndici();
  return new Response(foreign.body, foreign); // native Response, stream body passes
});
Defensive patterns

Strategy: validation

Validate before calling

// Before returning anything that might be foreign, verify the body type:
const body = candidate.body;
if (
  body !== null &&
  typeof body !== 'string' &&
  !(body instanceof Uint8Array) &&
  !(body instanceof Blob) &&
  !(body instanceof ReadableStream)
) {
  throw new Error(`Unsupported response body: ${Object.prototype.toString.call(body)}`);
}
return candidate instanceof Response ? candidate : new Response(body, candidate);

Type guard

const isServableBody = (b: unknown): b is BodyInit =>
  b === null ||
  typeof b === 'string' ||
  b instanceof Uint8Array ||
  b instanceof Blob ||
  b instanceof ReadableStream;

Prevention

When it happens

Trigger: Returning a Response created by another package's Response class (undici, node-fetch, a test double), returning an object that only duck-types Response after prototype checks were bypassed, or a bundler/polyfill replacing globalThis.Response before Deno.serve inspects the returned value.

Common situations: SSR/framework code bundled with a fetch polyfill for Node compatibility, unit-test Response mocks accidentally used in a live server, monorepos where a shared package exports its own Response implementation.

Related errors


AI-assisted analysis of denoland/deno@abd22074e4 (2026-08-20). Data as JSON: /api/errors/958fd14b95b7b535. Report an issue: GitHub.

Appendix: source

Thrown at ext/http/00_serve.ts:670

  if (typeof body === "string") {
    innerRequest?.close();
    if (headers?.length > 0) {
      op_http_set_response_body_text_with_headers(
        req,
        body,
        status,
        headers,
      );
    } else {
      op_http_set_response_body_text(req, body, status);
    }
    return;
  }

  // At this point in the response it needs to be a stream
  if (!ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, stream)) {
    innerRequest?.close();
    throw new TypeError("Invalid response");
  }
  setResponseHeaders(req, headers);
  const resourceBacking = getReadableStreamResourceBacking(stream);
  let rid, autoClose;
  if (resourceBacking) {
    rid = resourceBacking.rid;
    autoClose = resourceBacking.autoClose;
  } else {
    // The response headers/status have already been committed by the time the
    // body stream starts producing chunks, so an error thrown while draining
    // the stream (e.g. inside a `TransformStream` transformer) can no longer
    // change the response. Report it through the server's error handler so it
    // is not silently swallowed and a stack trace implicating the faulty
    // callback is surfaced. See https://github.com/denoland/deno/issues/19867.
    rid = resourceForReadableStream(stream, undefined, onError);
    autoClose = true;
  }
  PromisePrototypeThen(

View on GitHub (pinned to abd22074e4)