Short answer
No — Remix should not (and does not) automatically roll back loader data when an action throws, and that is not what is causing your hydration error. These are two separate concerns that are easy to conflate when they surface together after a schema change.
What is actually happening
The hydration error means the HTML your server rendered does not structurally match what React produced on the client's first render. After a schema change, the classic cause is stale loader data: the server rendered with the new field shape, but the client revalidated against a cached loader JSON response (browser cache, service worker, or CDN) that still has the old shape. A conditional render like {data.newField && <span>…</span>} then takes different branches on each side, and hydration fails.
Action failure is a red herring here. When an action throws, Remix renders your route's ErrorBoundary with the existing loader data still in place — it does not mutate loader data, so there is nothing to "roll back." Loader data only changes on revalidation, which Remix triggers after a successful action. If you are seeing data revert visually, that is your own rollback logic in useTransition/useNavigation or an error boundary rendering different markup — and a boundary that renders different structure than the normal branch is itself a legitimate source of hydration mismatches if it renders during the initial pass.
Fix path for this case
- Open dev tools, disable cache, and hard-reload. If the error disappears, stale loader JSON was the cause.
- Compare the loader data serialized into the document HTML against the JSON returned by the client-side loader fetch in the Network tab. A key mismatch confirms it.
- Clear any service worker and purge CDN cache for loader/data routes after deploying a schema change.
- Make the component tolerant: handle missing or renamed fields with the same fallback on both sides, e.g.
{data.newField ?? null}, rather than branching on existence. - If the mismatch persists with confirmed-fresh data, look for nondeterminism introduced alongside the schema change —
Date.now(), Math.random(), locale formatting, or typeof window checks in render.
On the design questions
Automatic rollback of loader data on action failure would be the wrong default: the loader data was never changed by the action, and synthesizing a "previous" state would fight with error boundaries, which exist precisely so the application decides what a failure looks like. Keep rollback in application code — optimistic UI via useNavigation (v2) / useTransition (v1) with explicit revert is the supported pattern.
Version considerations
Data-loading internals differ across Remix versions: v1 uses per-route loader fetches, while v2 (later releases) moved toward a single-fetch strategy, which changes which URLs carry loader data and which cache headers apply. Before tuning cache behavior, confirm your version's data strategy in the Network tab rather than assuming. Also note useTransition was renamed to useNavigation in v2 — the rollback logic itself is unchanged.
One caveat: if your error boundary renders during the initial server pass (e.g., the loader itself throws after the schema change because old cached data fails validation), the mismatch may come from the boundary markup. Check whether the server document contains your error UI — if so, fix the loader's handling of legacy-shaped data rather than the hydration layer.