sveltejs/kit · error
Cannot `return redirect(...)` — use `redirect(...)` instead
Error message
Cannot `return redirect(...)` — use `redirect(...)` instead
What it means
SvelteKit's `redirect(303, url)` throws a special `Redirect` internal object to abort execution; the framework catches it at the request boundary. Returning the `Redirect` instance from an action breaks that contract, so `validate_action_return` throws to force the correct throw-style usage.
Source
Thrown at packages/kit/src/runtime/server/page/actions.js:279
action(traced_event)
);
if (result instanceof ActionFailure) {
current.setAttributes({
'sveltekit.form_action.result.type': 'failure',
'sveltekit.form_action.result.status': result.status
});
}
return result;
}
});
}
/** @param {any} data */
function validate_action_return(data) {
if (data instanceof Redirect) {
throw new Error('Cannot `return redirect(...)` — use `redirect(...)` instead');
}
if (data instanceof HttpError) {
throw new Error('Cannot `return error(...)` — use `error(...)` or `return fail(...)` instead');
}
}
/**
* Try to `devalue.uneval` the data object, and if it fails, return a proper Error with context
* @param {any} data
* @param {string} route_id
*/
export function uneval_action_response(data, route_id) {
return try_serialize(data, uneval, route_id);
}
/**
* @param {any} dataView on GitHub (pinned to 03f1687fe6)
Solutions
- Replace `return redirect(status, location)` with `throw redirect(status, location)`
- Import `redirect` from '@sveltejs/kit' and ensure no code catches the thrown Redirect before SvelteKit handles it
Example fix
// before
export const actions = {
logout: async () => {
return redirect(303, '/');
}
};
// after
import { redirect } from '@sveltejs/kit';
export const actions = {
logout: async () => {
redirect(303, '/');
}
}; Defensive patterns
Strategy: validation
Prevention
- Always call `redirect(...)` without return/throw keyword — it throws itself
- Enable the eslint rule / review lints warning on returning kit helpers
- Update team snippets and AI prompts to SvelteKit 2 semantics
When it happens
Trigger: Writing `return redirect(303, '/path')` instead of `throw redirect(303, '/path')` inside a `+page.server.js` action (or load/runner that flows through the action return validator).
Common situations: Copy-pasted `return error(...)`/`return redirect(...)` from outdated blog posts or AI snippets; SvelteKit 1.x to newer migration where `redirect()` used to be thrown by `@sveltejs/kit` differently; confusion with returning other values from actions.
Related errors
- Cannot `return error(...)` — use `error(...)` or `return fai
- Invalid status code
- Invalid redirect location ${JSON.stringify(location)}: this
- Cannot redirect to external URL ${JSON.stringify(location)}.
- Cannot redirect to ${JSON.stringify(location)} with `{ exter
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/87a1d7b7f0f5b71d.
Report an issue: GitHub.