{"record":{"id":"4c26f7b7e773b20d","repo":"sveltejs/kit","slug":"cannot-use-setheaders-after-the-response-ha","errorCode":null,"errorMessage":"Cannot use `setHeaders(...)` after the response has been generated","messagePattern":"Cannot use `setHeaders\\(\\.\\.\\.\\)` after the response has been generated","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/runtime/server/respond.js","lineNumber":797,"sourceCode":"\t\t\t// so we need to make an actual HTTP request\n\t\t\tconst response = await fetch(request);\n\n\t\t\t// clone the response so that headers are mutable (https://github.com/sveltejs/kit/issues/13857)\n\t\t\treturn new Response(response.body, response);\n\t\t} catch (e) {\n\t\t\t// TODO if `e` is instead named `error`, some fucked up Vite transformation happens\n\t\t\t// and I don't even know how to describe it. need to investigate at some point\n\n\t\t\t// HttpError from endpoint can end up here - TODO should it be handled there instead?\n\t\t\treturn await handle_fatal_error(event, state, e);\n\t\t} finally {\n\t\t\tevent.cookies.set = () => {\n\t\t\t\tthrow new Error('Cannot use `cookies.set(...)` after the response has been generated');\n\t\t\t};\n\n\t\t\t// @ts-expect-error this has to be assigned lazily\n\t\t\tevent.setHeaders = () => {\n\t\t\t\tthrow new Error('Cannot use `setHeaders(...)` after the response has been generated');\n\t\t\t};\n\t\t}\n\t}\n}\n\n/**\n * @param {import('types').PageNodeIndexes} page\n */\nexport function load_page_nodes(page) {\n\treturn Promise.all([\n\t\t// we use == here rather than === because [undefined] serializes as \"[null]\"\n\t\t...page.layouts.map((n) => (n == undefined ? n : manifest.nodes[n]())),\n\t\tmanifest.nodes[page.leaf]()\n\t]);\n}\n\n/**\n * It's likely that, in a distributed system, there are spans starting outside the SvelteKit server -- eg.","sourceCodeStart":779,"sourceCodeEnd":815,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/runtime/server/respond.js#L779-L815","documentation":"Same guard as cookies.set: once resolve() has produced the Response, event.setHeaders is overwritten with a throwing function. Headers can no longer be applied to an already-built response, so the framework turns the no-op into a visible error.","triggerScenarios":"Calling event.setHeaders inside a streaming promise callback, a detached async continuation, or an after-response hook; calling setHeaders in code invoked from a setTimeout after the handler returns.","commonSituations":"Attempt to set cache-control after a slow stream starts; refactored shared helper that receives event and calls setHeaders, invoked post-resolution.","solutions":["Call setHeaders synchronously within the load function, action, endpoint handler, or before resolve(event) in the handle hook","For streamed chunks, set headers on the individual chunk Response rather than via event.setHeaders","Audit async helpers for deferred setHeaders calls and pass header values back to the main handler instead"],"exampleFix":"// before\nexport const load = async (event) => {\n  setTimeout(() => event.setHeaders({ 'cache-control': 'no-cache' }), 0); // throws\n  return { data };\n};\n// after\nexport const load = async (event) => {\n  event.setHeaders({ 'cache-control': 'no-cache' });\n  return { data };\n};","handlingStrategy":"try-catch","validationCode":"function canSetHeaders(event) {\n  try { event.setHeaders({}); return true; } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  event.setHeaders({ 'cache-control': 'no-store' });\n} catch {\n  // too late in lifecycle; set headers earlier or on the chunk Response\n  console.warn('setHeaders called after response generated');\n}","preventionTips":["Call setHeaders synchronously before the first await in load/handle","Never call setHeaders in setTimeout/stream callbacks","Pass header intents back to the main handler instead of calling from helpers post-resolution"],"tags":["http-headers","sveltekit","lifecycle"],"backgroundTag":"setheaders-after-response","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}