{"record":{"id":"43b40eec402e4d12","repo":"denoland/deno","slug":"first-argument-to-respondwith-must-be-a-response","errorCode":null,"errorMessage":"First argument to 'respondWith' must be a Response or a promise resolving to a Response","messagePattern":"First argument to 'respondWith' must be a Response or a promise resolving to a Response","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/http/01_http.js","lineNumber":201,"sourceCode":"        const reqEvt = await httpConn.nextRequest();\n        // Change with caution, current form avoids a v8 deopt\n        return { value: reqEvt ?? undefined, done: reqEvt === null };\n      },\n    };\n  }\n}\n\nfunction createRespondWith(\n  httpConn,\n  request,\n  readStreamRid,\n  writeStreamRid,\n) {\n  return async function respondWith(resp) {\n    try {\n      resp = await resp;\n      if (!(ObjectPrototypeIsPrototypeOf(ResponsePrototype, resp))) {\n        throw new TypeError(\n          \"First argument to 'respondWith' 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      // that don't carry the internal slot (e.g. `Object.create(Response.prototype)`\n      // or a polyfilled/foreign-realm Response). Reject those here instead of\n      // crashing later on `innerResp.body`. Mirrors the Deno.serve guard\n      // added in #34416.\n      const innerResp = toInnerResponse(resp);\n      if (innerResp === undefined) {\n        throw new TypeError(\n          \"First argument to 'respondWith' must be a Response constructed via the Response constructor in this realm\",\n        );\n      }\n\n      // If response body length is known, it will be sent synchronously in a\n      // single op, in other case a \"response body\" resource will be created and","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/http/01_http.js#L183-L219","documentation":"`Deno.HttpConn.respondWith()` (the low-level API obtained from `Deno.serveHttp(conn)`) accepts only a `Response` instance or a promise resolving to one. Before writing to the socket, Deno awaits the value and verifies it is on the `Response.prototype` chain; anything else — a string, plain object, `undefined`, a `Request` — throws this TypeError and the request fails.","triggerScenarios":"`requestEvent.respondWith(\"hello\")`; `respondWith({ status: 200 })`; an async handler that forgets `return` before `new Response(...)` so the awaited promise resolves to `undefined`; passing a `Request` back by mistake.","commonSituations":"Migrating from service-worker fetch-event or Express-style `(req, res)` handlers; refactors that drop the return statement; responding with serialized JSON instead of a Response object.","solutions":["Wrap the payload: `respondWith(new Response(body, { status, headers }))`","Check async handlers actually `return` the Response","If you return a promise, make sure it resolves to a real `Response`"],"exampleFix":"// before\nawait requestEvent.respondWith(JSON.stringify(data));\n\n// after\nawait requestEvent.respondWith(\n  new Response(JSON.stringify(data), { headers: { \"content-type\": \"application/json\" } }),\n);","handlingStrategy":"type-guard","validationCode":"const resp = await maybePromise;\nif (!(resp instanceof Response)) {\n  throw new TypeError(\"handler must return a Response\");\n}\nawait e.respondWith(resp);","typeGuard":"const isResponse = (v: unknown): v is Response => v instanceof Response;","tryCatchPattern":"try {\n  await e.respondWith(handler(requestEvent.request));\n} catch (err) {\n  if (err instanceof TypeError && err.message.includes(\"respondWith\")) {\n    await e.respondWith(new Response(\"handler error\", { status: 500 }));\n  } else throw err;\n}","preventionTips":["Always construct the reply with `new Response(...)` — never return raw strings/objects","Type handlers as `(req: Request) => Response | Promise<Response>` so the compiler catches it","Check that async handlers `return` the Response, not just build it"],"tags":["http","respondwith","servehttp","fetch-api"],"backgroundTag":"invalid-response-type","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}