remix-run/react-router · error · Error

Module cannot have both a HydrateFallback export and a Serve

Error message

Module cannot have both a HydrateFallback export and a ServerHydrateFallback export

What it means

Runtime guard in frameworkRoute(): a route module cannot export both `HydrateFallback` (client) and `ServerHydrateFallback` (server). Thrown at module load when both are present and truthy. The framework uses one hydrate-fallback per route.

Source

Thrown at packages/react-router-dev/vite/rsc/virtual-route-config.ts:50

        throw new Error("Module cannot have both a Layout export and a ServerLayout export");
      }
      Layout = mod.Layout;
    } else if ("ServerLayout" in mod && mod.ServerLayout) {
      Layout = mod.ServerLayout;
    }
    if ("ErrorBoundary" in mod && mod.ErrorBoundary) {
      if ("ServerErrorBoundary" in mod && mod.ServerErrorBoundary) {
        throw new Error(
          "Module cannot have both an ErrorBoundary export and a ServerErrorBoundary export",
        );
      }
      ErrorBoundary = mod.ErrorBoundary;
    } else if ("ServerErrorBoundary" in mod && mod.ServerErrorBoundary) {
      ErrorBoundary = mod.ServerErrorBoundary;
    }
    if ("HydrateFallback" in mod && mod.HydrateFallback) {
      if ("ServerHydrateFallback" in mod && mod.ServerHydrateFallback) {
        throw new Error(
          "Module cannot have both a HydrateFallback export and a ServerHydrateFallback export",
        );
      }
      HydrateFallback = mod.HydrateFallback;
    } else if ("ServerHydrateFallback" in mod && mod.ServerHydrateFallback) {
      HydrateFallback = mod.ServerHydrateFallback;
    }

    const {
      action,
      clientAction,
      clientLoader,
      clientMiddleware,
      handle,
      headers,
      links,
      loader,
      meta,

View on GitHub (pinned to 1fd704a7da)

Solutions

  1. Keep a single fallback export: `ServerHydrateFallback` for RSC routes, or `HydrateFallback` for client routes.
  2. Regenerate types and fix every flagged module.

Example fix

// app/routes/foo.tsx
// before
export function HydrateFallback() { return <p>loading…</p>; }
export function ServerHydrateFallback() { return <p>server loading…</p>; }
// after (server only)
export function ServerHydrateFallback() { return <p>server loading…</p>; }
Defensive patterns

Strategy: validation

Validate before calling

const src = readFileSync(routeFile, 'utf8');
const hasH = /export\s+(async\s+)?function\s+HydrateFallback\b/.test(src);
const hasSH = /export\s+(async\s+)?function\s+ServerHydrateFallback\b/.test(src);
if (hasH && hasSH) throw new Error(`${routeFile}: cannot export both HydrateFallback and ServerHydrateFallback`);

Type guard

function moduleExportsOnlyOneHydrateFallback(mod: Record<string, unknown>): boolean {
  return !mod.HydrateFallback || !mod.ServerHydrateFallback;
}

Prevention

When it happens

Trigger: A route module exports both `HydrateFallback` and `ServerHydrateFallback`. The `if ('HydrateFallback' in mod && mod.HydrateFallback)` branch detects the coexistence and throws.

Common situations: Adding a server fallback while a client fallback from Framework Mode is still present. Hybrid examples that demonstrate both exports.

Related errors


AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12). Data as JSON: /api/errors/265c7bb4cf3c1245. Report an issue: GitHub.