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} data

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Replace `return redirect(status, location)` with `throw redirect(status, location)`
  2. 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

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


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