{"record":{"id":"3274ed30cbe8a7a0","repo":"denoland/deno","slug":"err-http-headers-sent-3274ed","errorCode":"ERR_HTTP_HEADERS_SENT","errorMessage":"Cannot write headers after they are sent to the client","messagePattern":"Cannot write headers after they are sent to the client","errorType":"exception","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_http_server.js","lineNumber":424,"sourceCode":"  this.socket = null;\n};\n\nServerResponse.prototype.writeContinue = function writeContinue(cb) {\n  this._writeRaw(\"HTTP/1.1 100 Continue\\r\\n\\r\\n\", \"ascii\", cb);\n  this._sent100 = true;\n};\n\nServerResponse.prototype.writeProcessing = function writeProcessing(cb) {\n  this._writeRaw(\"HTTP/1.1 102 Processing\\r\\n\\r\\n\", \"ascii\", cb);\n};\n\nServerResponse.prototype.writeInformation = function writeInformation(\n  statusCode,\n  headers,\n  cb,\n) {\n  if (this._header) {\n    throw new ERR_HTTP_HEADERS_SENT(\"write\");\n  }\n\n  if (typeof headers === \"function\") {\n    cb = headers;\n    headers = undefined;\n  }\n\n  validateInteger(statusCode, \"statusCode\", 100, 199);\n\n  let head = `HTTP/1.1 ${statusCode} ${\n    STATUS_CODES[statusCode] || \"unknown\"\n  }\\r\\n`;\n\n  if (headers !== null && headers !== undefined) {\n    const keys = ObjectKeys(headers);\n    for (let i = 0; i < keys.length; i++) {\n      const key = keys[i];\n      validateHeaderName(key);","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/node/polyfills/_http_server.js#L406-L442","documentation":"ServerResponse.prototype.writeInformation (the path behind 1xx informational responses such as 102 Processing and 103 Early Hints) throws ERR_HTTP_HEADERS_SENT when this._header is already truthy: the final response's headers were already stored by an earlier writeHead or an implicit header flush. Informational responses are only legal before the final response begins, so the polyfill refuses to send them afterwards, matching Node.","triggerScenarios":"Calling res.writeInformation(status, headers) or res.writeProcessing() after res.writeHead(), res.end(), or a res.write() that flushed the implicit header; early-hints middleware that runs after the route handler already started the response.","commonSituations":"Early-hints middleware ordered after the handler; streaming handlers that emit 102 Processing after the body started; retry/progress wrappers that report status too late in the request lifecycle.","solutions":["Emit informational (1xx) responses before any writeHead/write/end on the final response","Guard every call with if (!res.headersSent && !res._header)","Fix middleware ordering so hints run at the top of the pipeline","Once headers are sent, drop the hint - late 1xx carries no value to the client anyway"],"exampleFix":"// before\nres.writeHead(200, { 'content-type': 'text/html' });\nres.writeInformation(103, { link: '</style.css>' }); // throws\n\n// after\nif (!res.headersSent && !res._header) {\n  res.writeInformation(103, { link: '</style.css>' });\n}\nres.writeHead(200, { 'content-type': 'text/html' });","handlingStrategy":"validation","validationCode":"function canSendInformational(res) {\n  return !res.headersSent && !res._header;\n}\nif (canSendInformational(res)) {\n  res.writeInformation(103, { 'link': '</style.css>' });\n}","typeGuard":null,"tryCatchPattern":"try {\n  res.writeInformation(102);\n} catch (e) {\n  if (e.code === 'ERR_HTTP_HEADERS_SENT') {\n    // final headers already flushed: skip the informational response\n  } else throw e;\n}","preventionTips":["Emit 1xx responses at the top of the request pipeline, before any handler output","Treat res.headersSent as a hard gate for every informational write","Log skipped hints in tests so middleware ordering regressions surface early"],"tags":["http","node-compat","early-hints","server"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}