{"record":{"id":"265c7bb4cf3c1245","repo":"remix-run/react-router","slug":"module-cannot-have-both-a-hydratefallback-export-a","errorCode":null,"errorMessage":"Module cannot have both a HydrateFallback export and a ServerHydrateFallback export","messagePattern":"Module cannot have both a HydrateFallback export and a ServerHydrateFallback export","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router-dev/vite/rsc/virtual-route-config.ts","lineNumber":50,"sourceCode":"        throw new Error(\"Module cannot have both a Layout export and a ServerLayout export\");\n      }\n      Layout = mod.Layout;\n    } else if (\"ServerLayout\" in mod && mod.ServerLayout) {\n      Layout = mod.ServerLayout;\n    }\n    if (\"ErrorBoundary\" in mod && mod.ErrorBoundary) {\n      if (\"ServerErrorBoundary\" in mod && mod.ServerErrorBoundary) {\n        throw new Error(\n          \"Module cannot have both an ErrorBoundary export and a ServerErrorBoundary export\",\n        );\n      }\n      ErrorBoundary = mod.ErrorBoundary;\n    } else if (\"ServerErrorBoundary\" in mod && mod.ServerErrorBoundary) {\n      ErrorBoundary = mod.ServerErrorBoundary;\n    }\n    if (\"HydrateFallback\" in mod && mod.HydrateFallback) {\n      if (\"ServerHydrateFallback\" in mod && mod.ServerHydrateFallback) {\n        throw new Error(\n          \"Module cannot have both a HydrateFallback export and a ServerHydrateFallback export\",\n        );\n      }\n      HydrateFallback = mod.HydrateFallback;\n    } else if (\"ServerHydrateFallback\" in mod && mod.ServerHydrateFallback) {\n      HydrateFallback = mod.ServerHydrateFallback;\n    }\n\n    const {\n      action,\n      clientAction,\n      clientLoader,\n      clientMiddleware,\n      handle,\n      headers,\n      links,\n      loader,\n      meta,","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router-dev/vite/rsc/virtual-route-config.ts#L32-L68","documentation":"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.","triggerScenarios":"A route module exports both `HydrateFallback` and `ServerHydrateFallback`. The `if ('HydrateFallback' in mod && mod.HydrateFallback)` branch detects the coexistence and throws.","commonSituations":"Adding a server fallback while a client fallback from Framework Mode is still present. Hybrid examples that demonstrate both exports.","solutions":["Keep a single fallback export: `ServerHydrateFallback` for RSC routes, or `HydrateFallback` for client routes.","Regenerate types and fix every flagged module."],"exampleFix":"// app/routes/foo.tsx\n// before\nexport function HydrateFallback() { return <p>loading…</p>; }\nexport function ServerHydrateFallback() { return <p>server loading…</p>; }\n// after (server only)\nexport function ServerHydrateFallback() { return <p>server loading…</p>; }","handlingStrategy":"validation","validationCode":"const src = readFileSync(routeFile, 'utf8');\nconst hasH = /export\\s+(async\\s+)?function\\s+HydrateFallback\\b/.test(src);\nconst hasSH = /export\\s+(async\\s+)?function\\s+ServerHydrateFallback\\b/.test(src);\nif (hasH && hasSH) throw new Error(`${routeFile}: cannot export both HydrateFallback and ServerHydrateFallback`);","typeGuard":"function moduleExportsOnlyOneHydrateFallback(mod: Record<string, unknown>): boolean {\n  return !mod.HydrateFallback || !mod.ServerHydrateFallback;\n}","tryCatchPattern":null,"preventionTips":["Choose one fallback export per route.","Run typegen after edits to surface duplicates."],"tags":["rsc","route-module","exports","hydrate-fallback"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}