sveltejs/kit · warning

The form action returned an error, but +error.svelte wasn't

Error message

The form action returned an error, but +error.svelte wasn't rendered because SSR is off. To get the error page with CSR, enhance your form with `use:enhance`. See https://svelte.dev/docs/kit/form-actions#progressive-enhancement-use-enhance

What it means

When a form posts to an action without `use:enhance` and SSR is off, SvelteKit has no way to render the returned error page or deliver the action result to `page.form` — the value is silently lost. In dev, this warning explains why the result vanished and points to progressive enhancement.

Source

Thrown at packages/kit/src/runtime/server/page/index.js:122

		/** @type {import('./types.js').Fetched[]} */
		const fetched = [];

		const ssr = nodes.ssr();
		const csr = nodes.csr();

		// renders an empty 'shell' page if SSR is turned off and if there is
		// no server data to prerender. As a result, the load functions and rendering
		// only occur client-side.
		if (
			ssr === false &&
			!((state.prerendering || state.prerender_default === true) && should_prerender_data)
		) {
			// if the user makes a request through a non-enhanced form, the returned value is lost
			// because there is no SSR or client-side handling of the response
			if (DEV && action_result && !event.request.headers.has('x-sveltekit-action')) {
				if (action_result.type === 'error') {
					console.warn(
						"The form action returned an error, but +error.svelte wasn't rendered because SSR is off. To get the error page with CSR, enhance your form with `use:enhance`. See https://svelte.dev/docs/kit/form-actions#progressive-enhancement-use-enhance"
					);
				} else if (action_result.data) {
					/// case: lost data
					console.warn(
						"The form action returned a value, but it isn't available in `page.form`, because SSR is off. To handle the returned value in CSR, enhance your form with `use:enhance`. See https://svelte.dev/docs/kit/form-actions#progressive-enhancement-use-enhance"
					);
				}
			}

			return await render_response({
				// provide nodes without running load functions so that the styles and
				// fonts are linked in the head before CSR takes over
				branch: compact(nodes.data).map((node) => {
					return {
						node,
						data: null,
						server_data: null

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Add `use:enhance` from `$app/forms` to the form element
  2. Re-enable SSR for pages whose actions return errors/data
  3. Handle failures client-side yourself with a custom submit handler

Example fix

<!-- before -->
<form method="POST" action="?/create">
<!-- after -->
<script>
import { enhance } from '$app/forms';
</script>
<form method="POST" action="?/create" use:enhance>
Defensive patterns

Strategy: fallback

Validate before calling

// detect the risky combination before submit
if (!formEl.dataset.enhanced && !document.documentElement.dataset.ssr) {
  console.warn('Action results will be lost: add use:enhance or enable SSR');
}

Prevention

When it happens

Trigger: A plain `<form method="POST" action="?/action">` (no `use:enhance`) submits, the action returns `fail(...)`/`error(...)` (type 'error'), and the page is rendered with `ssr = false` (or prerendering config skips SSR), detected via absence of the `x-sveltekit-action` header in dev.

Common situations: Disabling SSR per-page or globally while keeping plain HTML forms; forgetting `use:enhance` when moving a page to CSR-only; prerender-enabled apps receiving action POSTs.

Related errors


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