sveltejs/kit · error

setHeaders is not allowed in remote functions

Error message

setHeaders is not allowed in remote functions

What it means

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.

Source

Thrown at packages/kit/src/runtime/app/server/remote/shared.js:87

		// if this is a top-level (not nested) `await myQuery()`, include it in the serialized response
		get_implicit_lookup(internals, state)[payload] = get_result;
	}

	return (cache[payload] ??= get_result());
}

/**
 * @param {RequestEvent} event
 * @param {RequestState} state
 * @param {boolean} allow_cookies
 * @returns {RequestStore}
 */
function derive_remote_function_event(event, state, allow_cookies) {
	/** @type {RequestEvent} */
	const derived = {
		...event,
		setHeaders: () => {
			throw new Error('setHeaders is not allowed in remote functions');
		},
		cookies: {
			...event.cookies,
			set: (name, value, opts) => {
				if (!allow_cookies) {
					throw new Error('Cannot set cookies in `query` or `prerender` functions');
				}

				if (opts.path && !opts.path.startsWith('/')) {
					throw new Error('Cookies set in remote functions must have an absolute path');
				}

				return event.cookies.set(name, value, opts);
			},
			delete: (name, opts) => {
				if (!allow_cookies) {
					throw new Error('Cannot delete cookies in `query` or `prerender` functions');
				}

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Remove the `event.setHeaders` call from the remote function.
  2. Move the logic that needs header control into a `+page.server.js/ts` load function or a route handler.
  3. Make shared helpers take a flag (or check context) so they only set headers outside remote functions.

Example fix

// before
export const getData = query(async (event, id) => {
  event.setHeaders({ 'cache-control': 'max-age=60' });
  return db.get(id);
});
// after
export const getData = query(async (event, id) => {
  return db.get(id); // no header manipulation in remote functions
});
Defensive patterns

Strategy: type-guard

Type guard

function inRemoteFunction(store) {
  return store?.state?.is_in_remote_query === true; // check before calling event.setHeaders
}

Try / catch

try {
  event.setHeaders({ 'cache-control': 'max-age=60' });
} catch {
  // headers not settable in remote functions — proceed without
}

Prevention

When it happens

Trigger: Calling `event.setHeaders({ 'cache-control': ... })` (or any header) inside the body of a remote function in a `.remote.js/ts` file.

Common situations: 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.

Related errors


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/d3973895dedad494. Report an issue: GitHub.