{"record":{"id":"8c8e47a07c51a39a","repo":"denoland/deno","slug":"return-value-from-serve-handler-must-not-be-an-err","errorCode":null,"errorMessage":"Return value from serve handler must not be an error response (like Response.error())","messagePattern":"Return value from serve handler must not be an error response \\(like Response\\.error\\(\\)\\)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/http/00_serve.ts","lineNumber":741,"sourceCode":"      if (!ObjectPrototypeIsPrototypeOf(ResponsePrototype, response)) {\n        throw new TypeError(\n          \"Return value from serve handler must be a response or a promise resolving to a response\",\n        );\n      }\n\n      // The Response prototype check above passes for Response-like objects\n      // (e.g. a subclass that skipped super(), or a Response from a different\n      // realm/polyfill). Those don't carry the internal slot we read from\n      // below, so reject them with a clear error instead of crashing later.\n      inner = getInnerResponse(response);\n      if (inner === undefined) {\n        throw new TypeError(\n          \"Return value from serve handler must be a Response constructed via the Response constructor in this realm\",\n        );\n      }\n\n      if (inner.type === \"error\") {\n        throw new TypeError(\n          \"Return value from serve handler must not be an error response (like Response.error())\",\n        );\n      }\n\n      if (responseBodyUsed(response)) {\n        throw new TypeError(\n          \"The body of the Response returned from the serve handler has already been consumed\",\n        );\n      }\n    } catch (error) {\n      try {\n        response = await onError(error);\n        if (!ObjectPrototypeIsPrototypeOf(ResponsePrototype, response)) {\n          throw new TypeError(\n            \"Return value from onError handler must be a response or a promise resolving to a response\",\n          );\n        }\n        inner = toInnerResponse(response);","sourceCodeStart":723,"sourceCodeEnd":759,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/http/00_serve.ts#L723-L759","documentation":"Response.error() is a spec-defined network-error marker with type 'error' and no transmissible status, headers, or body, so it cannot be served meaningfully. When a handler returns one, serve inspects the internal response type and throws this TypeError; onError then handles it (default: 500).","triggerScenarios":"Returning Response.error() from the handler as an error signal; propagating a Response.error() produced by fetch() failure paths back out of a proxy handler.","commonSituations":"Copy-pasted fetch-wrapper code that returns Response.error() on catch; using Response.error() as a sentinel value in routing code.","solutions":["Return a real status instead: new Response('Service Unavailable', { status: 503 })","Or throw an Error from the handler and let onError produce the 500 response","If wrapping fetch(), map failed upstream calls to a synthetic 502/504 Response"],"exampleFix":"// before\nDeno.serve(async (req) => {\n  try {\n    return await fetch(req);\n  } catch {\n    return Response.error(); // cannot be served\n  }\n});\n\n// after\nDeno.serve(async (req) => {\n  try {\n    return await fetch(req);\n  } catch {\n    return new Response(\"Bad Gateway\", { status: 502 });\n  }\n});","handlingStrategy":"type-guard","validationCode":"// Replace error-type responses with a servable one before returning\nif (response.type === \"error\") {\n  response = new Response(\"Service Unavailable\", { status: 503 });\n}\nreturn response;","typeGuard":"function isServableResponse(v) {\n  return v instanceof Response && v.type !== \"error\";\n}","tryCatchPattern":"Deno.serve({\n  onError: (err) => new Response(\"Internal Server Error\", { status: 500 }),\n  handler,\n}); // Response.error() rejections land here as a 500","preventionTips":["Never return Response.error() from a serve handler","Throw plain Errors and let onError shape the error response","Map upstream fetch failures to explicit 502/503/504 responses"],"tags":["http","serve","response","handler"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}