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: nullView on GitHub (pinned to 03f1687fe6)
Solutions
- Add `use:enhance` from `$app/forms` to the form element
- Re-enable SSR for pages whose actions return errors/data
- 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
- Always add use:enhance to forms posting to actions
- Avoid ssr=false on pages with form actions
- Test action error paths with SSR disabled in dev to catch this early
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
- The properties of `form.fields` are virtual, so operators li
- \u001B[1m\u001B[31mRemoving comments in transformPageChunk c
- \u001B[1m\u001B[31mReturning promises from server `load` fun
- Cannot access cloudflare:workers in a prerenderable route
- The configured Vite SSR environment must be a RunnableDevEnv
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/9d5ce1d3220a2581.
Report an issue: GitHub.