sveltejs/kit · error · Error

${keypath} should be a function, if specified

Error message

${keypath} should be a function, if specified

What it means

The `fun()` validator checks that an optional config option, when provided, is a function. If a non-function value is assigned to a hook or callback option (e.g. handle, handleError), SvelteKit throws this error at config load time.

Source

Thrown at packages/kit/src/core/config/options.js:500

			// prettier-ignore
			const msg = options.length > 2
				? `${keypath} should be one of ${options.slice(0, -1).map(input => `"${input}"`).join(', ')} or "${options[options.length - 1]}"`
				: `${keypath} should be either "${options[0]}" or "${options[1]}"`;

			throw new Error(msg);
		}
		return input;
	});
}

/**
 * @param {(...args: any) => any} fallback
 * @returns {Validator}
 */
function fun(fallback) {
	return validate(fallback, (input, keypath) => {
		if (typeof input !== 'function') {
			throw new Error(`${keypath} should be a function, if specified`);
		}
		return input;
	});
}

function any() {
	return validate(undefined, (input) => input);
}

/**
 * @param {string} input
 * @param {string} keypath
 */
function assert_string(input, keypath) {
	if (typeof input !== 'string') {
		throw new Error(`${keypath} should be a string, if specified`);
	}
}

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Open svelte.config.js and locate the option named in the keypath.
  2. Ensure the value is a function reference, not a call result or string.
  3. Import the hook correctly: `handle: import('./hooks.server').then(m => m.handle)` is not allowed — use a direct function import or define it inline.

Example fix

// before
kit: { handle: './src/hooks.server.js' }
// after
import handle from './src/hooks.server.js';
const config = { kit: { handle } };
Defensive patterns

Strategy: type-guard

Validate before calling

if (config.kit?.handle !== undefined && typeof config.kit.handle !== 'function') {
  throw new Error('kit.handle must be a function');
}

Type guard

function isFunction(v) {
  return typeof v === 'function';
}

Try / catch

try {
  build(config);
} catch (e) {
  if (String(e.message).includes('should be a function')) {
    console.error('Config hook is not a function — check for accidental invocation: use fn, not fn()');
  } else throw e;
}

Prevention

When it happens

Trigger: Assigning a non-function to a function-typed kit config option, e.g. `handle: './hooks'` (string) or `handle: myMiddleware()` (invoked result) instead of `handle: myMiddleware`.

Common situations: Accidentally invoking the hook function instead of passing it; importing the wrong export from hooks.server.js; passing an async wrapper incorrectly or forgetting the export in a re-export chain.

Related errors


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