remix-run/react-router · error
Module cannot have both a default export and a…
Error message
Module cannot have both a default export and a ServerComponent export
What it means
In RSC mode, route modules are split into client and server portions, and a route's component can be supplied either by the client 'default' export or by the server 'ServerComponent' export — never both. The generated framework-route wrapper checks the module at render time: when 'default' is truthy and 'ServerComponent' is also present it throws, because it would be ambiguous which component should render.
Solutions
- Delete the 'default' export if the route should render on the server
- Delete 'ServerComponent' if the route must stay a client component
- Move any shared JSX/helpers into a separate imported module so only one component export remains
Example fix
// before — app/routes/dashboard.tsx
export default function Route() { return <h1>Client</h1>; }
export async function ServerComponent() { return <h1>Server</h1>; }
// after
export async function ServerComponent() { return <h1>Server</h1>; } Defensive patterns
Strategy: validation
Validate before calling
// dev-time scan: import each route module and check export pairs
const PAIRS = [["default", "ServerComponent"]] as const;
for (const file of routeFiles) {
const mod: Record<string, unknown> = await import(pathToFileURL(file).href);
for (const [client, server] of PAIRS) {
if (mod[client] && mod[server]) {
throw new Error(`${file}: export either ${client} or ${server}, not both`);
}
}
} Type guard
function hasComponentConflict(mod: Record<string, unknown>): boolean {
return Boolean(mod.default) && Boolean(mod.ServerComponent);
} Prevention
- When converting a route to RSC, delete the old default export in the same commit
- Adopt a naming convention where a route uses either client or server variants exclusively
- Run the RSC build in CI so the static pair validation (error 47) catches regressions
When it happens
Trigger: A route module containing both 'export default function Route()' and 'export async function ServerComponent()' (both truthy at module-evaluation time in the lazy-loaded route).
Common situations: Converting an existing Framework-mode route to RSC by adding ServerComponent while forgetting to delete the old default export; copy-pasting from examples that mix client and server component conventions in one file.
Related errors
- Invalid route module exports. The following pairs of…
- Module cannot have both a HydrateFallback export and a…
- Module cannot have both a Layout export and a ServerLayout…
- Module cannot have both an ErrorBoundary export and a…
- Error splitting route module
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/a721cd6ac55d6210.
Report an issue: GitHub.
Appendix: source
Thrown at packages/react-router-dev/vite/rsc/virtual-route-config.ts:24
export function createVirtualRouteConfig({
appDirectory,
routeConfig,
}: {
appDirectory: string;
routeConfig: RouteConfigEntry[];
}): { code: string; routeIdByFile: Map<string, string> } {
let routeIdByFile = new Map<string, string>();
let code = js`import * as React from "react";
function frameworkRoute(lazy) {
return async () => {
const mod = await lazy();
let Component;
let Layout;
let ErrorBoundary;
let HydrateFallback;
if ("default" in mod && mod.default) {
if ("ServerComponent" in mod && mod.ServerComponent) {
throw new Error("Module cannot have both a default export and a ServerComponent export");
}
Component = mod.default;
} else if ("ServerComponent" in mod && mod.ServerComponent) {
Component = mod.ServerComponent;
}
if ("Layout" in mod && mod.Layout) {
if ("ServerLayout" in mod && mod.ServerLayout) {
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",
);View on GitHub (pinned to 6beaca3952)