sveltejs/kit · error · Error
Cannot use `setHeaders(...)` after the response has been gen
Error message
Cannot use `setHeaders(...)` after the response has been generated
What it means
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.
Source
Thrown at packages/kit/src/runtime/server/respond.js:797
// so we need to make an actual HTTP request
const response = await fetch(request);
// clone the response so that headers are mutable (https://github.com/sveltejs/kit/issues/13857)
return new Response(response.body, response);
} catch (e) {
// TODO if `e` is instead named `error`, some fucked up Vite transformation happens
// and I don't even know how to describe it. need to investigate at some point
// HttpError from endpoint can end up here - TODO should it be handled there instead?
return await handle_fatal_error(event, state, e);
} finally {
event.cookies.set = () => {
throw new Error('Cannot use `cookies.set(...)` after the response has been generated');
};
// @ts-expect-error this has to be assigned lazily
event.setHeaders = () => {
throw new Error('Cannot use `setHeaders(...)` after the response has been generated');
};
}
}
}
/**
* @param {import('types').PageNodeIndexes} page
*/
export function load_page_nodes(page) {
return Promise.all([
// we use == here rather than === because [undefined] serializes as "[null]"
...page.layouts.map((n) => (n == undefined ? n : manifest.nodes[n]())),
manifest.nodes[page.leaf]()
]);
}
/**
* It's likely that, in a distributed system, there are spans starting outside the SvelteKit server -- eg.View on GitHub (pinned to 03f1687fe6)
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
Example fix
// before
export const load = async (event) => {
setTimeout(() => event.setHeaders({ 'cache-control': 'no-cache' }), 0); // throws
return { data };
};
// after
export const load = async (event) => {
event.setHeaders({ 'cache-control': 'no-cache' });
return { data };
}; Defensive patterns
Strategy: try-catch
Validate before calling
function canSetHeaders(event) {
try { event.setHeaders({}); return true; } catch { return false; }
} Try / catch
try {
event.setHeaders({ 'cache-control': 'no-store' });
} catch {
// too late in lifecycle; set headers earlier or on the chunk Response
console.warn('setHeaders called after response generated');
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Attempt to set cache-control after a slow stream starts; refactored shared helper that receives event and calls setHeaders, invoked post-resolution.
Related errors
- "${key}" header is already set
- Cannot use `cookies.set(...)` after the response has been ge
- The ${protocol_header} header specified ${protocol} which is
- Could not determine host from the ${host_header ? `${host_he
- The ${port_header} header specified ${port} which is an inva
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/4c26f7b7e773b20d.
Report an issue: GitHub.