{"record":{"id":"8318bcaccafdffbd","repo":"denoland/deno","slug":"cannot-read-headers-request-closed","errorCode":null,"errorMessage":"Cannot read headers: request closed","messagePattern":"Cannot read headers: request closed","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/fetch/23_request.js","lineNumber":146,"sourceCode":"    StringPrototypeStartsWith(url, \"blob:\")\n  ) {\n    blobUrlEntry = blobFromObjectUrl(url);\n  }\n  return {\n    methodInner: method,\n    get method() {\n      return this.methodInner;\n    },\n    set method(value) {\n      this.methodInner = value;\n    },\n    headerListInner: null,\n    get headerList() {\n      if (this.headerListInner === null) {\n        try {\n          this.headerListInner = headerList();\n        } catch {\n          throw new TypeError(\"Cannot read headers: request closed\");\n        }\n      }\n      return this.headerListInner;\n    },\n    set headerList(value) {\n      this.headerListInner = value;\n    },\n    body,\n    redirectMode: \"follow\",\n    redirectCount: 0,\n    urlList: [typeof url === \"string\" ? () => url : url],\n    urlListProcessed: [],\n    clientRid: null,\n    blobUrlEntry,\n    url() {\n      if (this.urlListProcessed[0] === undefined) {\n        try {\n          this.urlListProcessed[0] = this.urlList[0]();","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/fetch/23_request.js#L128-L164","documentation":"InnerRequest's headerList getter materializes headers lazily by calling the headerList() function captured at request creation. When that underlying source (an op-backed request, e.g. one deserialized from a server connection or transfer stream) has already been closed, the call throws and the getter converts it into TypeError 'Cannot read headers: request closed'. It means the request object outlived the resource that owns its header data.","triggerScenarios":"Reading request.headers (directly or via fetch internals) on an InnerRequest whose op resource was closed beforehand — e.g. a server-side or worker-transferred Request accessed after the connection/MessagePort that produced it closed.","commonSituations":"Stashing an incoming Request for later processing after the HTTP connection dropped, or after response completion when the runtime reaped the connection resource; race between an aborted client and handler code still inspecting headers.","solutions":["Copy out the headers (e.g. Object.fromEntries(request.headers)) synchronously when the request first arrives, before any await","Stop touching the Request after the connection/transfer that owns it closes; pass plain data to deferred work instead","Abort or finish in-flight request processing when the underlying connection's close/abort signal fires"],"exampleFix":"// before\nconst pending = [];\nDeno.serve((req) => {\n  pending.push(req); // kept past connection lifetime\n  return new Response('ok');\n});\n// later, connection already closed:\nfor (const r of pending) console.log(r.headers.get('x-id')); // throws\n\n// after\nconst pending = [];\nDeno.serve((req) => {\n  pending.push(Object.fromEntries(req.headers)); // snapshot now\n  return new Response('ok');\n});","handlingStrategy":"try-catch","validationCode":"function snapshotHeaders(req) {\n  try {\n    return Object.fromEntries(req.headers);\n  } catch {\n    return null; // request already closed\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  headers = Object.fromEntries(req.headers);\n} catch (err) {\n  if (err instanceof TypeError && err.message === 'Cannot read headers: request closed') {\n    // connection dropped; skip or use last-known snapshot\n  } else throw err;\n}","preventionTips":["Materialize headers synchronously when a request arrives, before any await","Never retain Request objects past response completion; keep plain snapshots","Watch request.signal.aborted and stop processing retained requests"],"tags":["fetch","request","lifecycle","race-condition","deno"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}