{"record":{"id":"d3973895dedad494","repo":"sveltejs/kit","slug":"setheaders-is-not-allowed-in-remote-functions","errorCode":null,"errorMessage":"setHeaders is not allowed in remote functions","messagePattern":"setHeaders is not allowed in remote functions","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/kit/src/runtime/app/server/remote/shared.js","lineNumber":87,"sourceCode":"\t\t// if this is a top-level (not nested) `await myQuery()`, include it in the serialized response\n\t\tget_implicit_lookup(internals, state)[payload] = get_result;\n\t}\n\n\treturn (cache[payload] ??= get_result());\n}\n\n/**\n * @param {RequestEvent} event\n * @param {RequestState} state\n * @param {boolean} allow_cookies\n * @returns {RequestStore}\n */\nfunction derive_remote_function_event(event, state, allow_cookies) {\n\t/** @type {RequestEvent} */\n\tconst derived = {\n\t\t...event,\n\t\tsetHeaders: () => {\n\t\t\tthrow new Error('setHeaders is not allowed in remote functions');\n\t\t},\n\t\tcookies: {\n\t\t\t...event.cookies,\n\t\t\tset: (name, value, opts) => {\n\t\t\t\tif (!allow_cookies) {\n\t\t\t\t\tthrow new Error('Cannot set cookies in `query` or `prerender` functions');\n\t\t\t\t}\n\n\t\t\t\tif (opts.path && !opts.path.startsWith('/')) {\n\t\t\t\t\tthrow new Error('Cookies set in remote functions must have an absolute path');\n\t\t\t\t}\n\n\t\t\t\treturn event.cookies.set(name, value, opts);\n\t\t\t},\n\t\t\tdelete: (name, opts) => {\n\t\t\t\tif (!allow_cookies) {\n\t\t\t\t\tthrow new Error('Cannot delete cookies in `query` or `prerender` functions');\n\t\t\t\t}","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/runtime/app/server/remote/shared.js#L69-L105","documentation":"Remote functions run in a derived request event whose `setHeaders` is intentionally replaced with a throwing stub. Response headers for remote calls are controlled by SvelteKit, not application code, so any `event.setHeaders(...)` call inside a `query`, `command`, `form`, or `prerender` remote function throws.","triggerScenarios":"Calling `event.setHeaders({ 'cache-control': ... })` (or any header) inside the body of a remote function in a `.remote.js/ts` file.","commonSituations":"Copy-pasting a `+page.server.ts` load function (which legitimately uses setHeaders) into a remote function; a shared helper used by both load functions and remote functions that sets caching headers.","solutions":["Remove the `event.setHeaders` call from the remote function.","Move the logic that needs header control into a `+page.server.js/ts` load function or a route handler.","Make shared helpers take a flag (or check context) so they only set headers outside remote functions."],"exampleFix":"// before\nexport const getData = query(async (event, id) => {\n  event.setHeaders({ 'cache-control': 'max-age=60' });\n  return db.get(id);\n});\n// after\nexport const getData = query(async (event, id) => {\n  return db.get(id); // no header manipulation in remote functions\n});","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function inRemoteFunction(store) {\n  return store?.state?.is_in_remote_query === true; // check before calling event.setHeaders\n}","tryCatchPattern":"try {\n  event.setHeaders({ 'cache-control': 'max-age=60' });\n} catch {\n  // headers not settable in remote functions — proceed without\n}","preventionTips":["Never copy load-function header code into .remote files.","Put header-controlled endpoints in +server.js or load functions instead.","Guard shared helpers before they touch event.setHeaders."],"tags":["remote-functions","headers","api-restriction"],"backgroundTag":"setheaders-not-allowed","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}