{"record":{"id":"59b23f9a050c19e9","repo":"remix-run/react-router","slug":"module-cannot-have-both-an-errorboundary-export-an","errorCode":null,"errorMessage":"Module cannot have both an ErrorBoundary export and a ServerErrorBoundary export","messagePattern":"Module cannot have both an ErrorBoundary export and a ServerErrorBoundary export","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router-dev/vite/rsc/virtual-route-config.ts","lineNumber":40,"sourceCode":"    if (\"default\" in mod && mod.default) {\n      if (\"ServerComponent\" in mod && mod.ServerComponent) {\n        throw new Error(\"Module cannot have both a default export and a ServerComponent export\");\n      }\n      Component = mod.default;\n    } else if (\"ServerComponent\" in mod && mod.ServerComponent) {\n      Component = mod.ServerComponent;\n    }\n    if (\"Layout\" in mod && mod.Layout) {\n      if (\"ServerLayout\" in mod && mod.ServerLayout) {\n        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","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router-dev/vite/rsc/virtual-route-config.ts#L22-L58","documentation":"Runtime guard in frameworkRoute(): a route module cannot export both `ErrorBoundary` (client) and `ServerErrorBoundary` (server). Thrown when both are truthy at module load inside the lazy resolver. The framework picks one error boundary per route; coexistence is ambiguous.","triggerScenarios":"A route module exports `export function ErrorBoundary()` and `export function ServerErrorBoundary()` simultaneously. The `if ('ErrorBoundary' in mod && mod.ErrorBoundary)` branch detects the pair and throws.","commonSituations":"Migrating an error boundary to RSC and leaving the client version. Copying a sample that had both for documentation purposes.","solutions":["Remove one of the two exports — typically keep `ServerErrorBoundary` for RSC routes, or `ErrorBoundary` for client-only routes.","Run typegen to get the duplicate-export compile-time error and fix all flagged modules."],"exampleFix":"// app/routes/foo.tsx\n// before\nexport function ErrorBoundary() { return <p>client err</p>; }\nexport function ServerErrorBoundary() { return <p>server err</p>; }\n// after (server only)\nexport function ServerErrorBoundary() { return <p>server err</p>; }","handlingStrategy":"validation","validationCode":"const src = readFileSync(routeFile, 'utf8');\nconst hasE = /export\\s+(async\\s+)?function\\s+ErrorBoundary\\b/.test(src);\nconst hasSE = /export\\s+(async\\s+)?function\\s+ServerErrorBoundary\\b/.test(src);\nif (hasE && hasSE) throw new Error(`${routeFile}: cannot export both ErrorBoundary and ServerErrorBoundary`);","typeGuard":"function moduleExportsOnlyOneErrorBoundary(mod: Record<string, unknown>): boolean {\n  return !mod.ErrorBoundary || !mod.ServerErrorBoundary;\n}","tryCatchPattern":null,"preventionTips":["Standardize on one error-boundary export per route.","Add a pre-commit grep for the pair."],"tags":["rsc","route-module","exports","error-boundary"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}