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
- Open svelte.config.js and locate the option named in the keypath.
- Ensure the value is a function reference, not a call result or string.
- 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
- Never append () when assigning hook functions in svelte.config.js.
- Verify the hook module's named export is a function before re-exporting it.
- Use JSDoc or types (import type { Handle }) so the editor flags non-function assignments.
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
- Invalid isr.expiration value: ${JSON.stringify(value)} (${de
- The SvelteKit options from the Vite config must be an object
- ${keypath} should be "fail", "warn", "ignore" or a custom fu
- The SvelteKit Vite plugin ${keypath} should be an object wit
- ${keypath} should be an object
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/1c0eb3433b70b336.
Report an issue: GitHub.