remix-run/react-router · error · Error
Error splitting route module: ${normalizeRelativeFilePath(id
Error message
Error splitting route module: ${normalizeRelativeFilePath(id, ctx.reactRouterConfig)}\n\n${invalidChunks.map((name) => `- ${name}`).join("\n")}\n\n${plural ? "These exports" : "This export"} could not be split into ${plural ? "their own chunks" : "its own chunk"} because ${plural ? "they share" : "it shares"} code with other exports. You should extract any shared code into its own module and then import it within the route module. What it means
Thrown by `validateRouteChunks` when one or more named route chunks (`clientAction`, `clientLoader`, `HydrateFallback`, `ErrorBoundary`) cannot be safely isolated. React Router splits these exports into separate chunks so the client doesn't download, e.g., the action code on first paint. If an export shares code (variables, helper functions, imports) with another export, the splitter would have to duplicate or pull in shared code, so it refuses and lists the offending chunk names.
Source
Thrown at packages/react-router-dev/vite/plugin.ts:3356
ctx: ReactRouterPluginContext;
id: string;
valid: Record<Exclude<RouteChunkName, "main">, boolean>;
}): void {
if (isRootRouteModuleId(ctx, id)) {
return;
}
let invalidChunks = Object.entries(valid)
.filter(([_, isValid]) => !isValid)
.map(([chunkName]) => chunkName);
if (invalidChunks.length === 0) {
return;
}
let plural = invalidChunks.length > 1;
throw new Error(
[
`Error splitting route module: ${normalizeRelativeFilePath(
id,
ctx.reactRouterConfig,
)}`,
invalidChunks.map((name) => `- ${name}`).join("\n"),
`${plural ? "These exports" : "This export"} could not be split into ${
plural ? "their own chunks" : "its own chunk"
} because ${
plural ? "they share" : "it shares"
} code with other exports. You should extract any shared code into its own module and then import it within the route module.`,
].join("\n\n"),
);
}
export async function cleanBuildDirectory(View on GitHub (pinned to 1fd704a7da)
Solutions
- Extract the shared code into its own module (a sibling `.ts` file) and import it from each export.
- Inline the shared logic per export if extraction is not desirable.
- Reduce cross-export coupling by passing data through arguments instead of module-scope variables.
- Rebuild — the listed chunk names tell you exactly which exports to refactor.
Example fix
// before: clientAction and clientLoader share a helper
const fetcher = (id) => api.get(`/x/${id}`);
export const clientAction = () => fetcher(1);
export const clientLoader = () => fetcher(2);
// after: extract shared helper
// app/routes/_shared.ts
export const fetcher = (id) => api.get(`/x/${id}`);
// app/routes/foo.ts
import { fetcher } from "./_shared";
export const clientAction = () => fetcher(1);
export const clientLoader = () => fetcher(2); Defensive patterns
Strategy: validation
Validate before calling
// Statically detect shared top-level identifiers across chunks
const findSharedBindings = (exports: string[], moduleScope: string[]) => {
return moduleScope.filter(name =>
exports.some(e => references(name, e)) &&
exports.some(e => e !== references && references(name, e)));
}; Prevention
- Extract shared helpers between `clientAction`/`clientLoader`/`ErrorBoundary` into separate files.
- Avoid module-scope mutable state shared across route chunks.
- Run a pre-build static analysis pass that flags shared identifiers across named chunks.
When it happens
Trigger: A route module declares `clientAction` and `clientLoader` that both reference a shared in-file helper or a shared top-level `const`; an `ErrorBoundary` that imports a large shared module also used by the route's `default`; route chunks that close over module-scope mutable state.
Common situations: Co-locating action/loader logic in one route file with shared helpers; refactoring that pulls shared utilities up to module scope; large route modules with intertwined exports.
Related errors
- Invalid route chunk name "${chunkName}" in "${id}"
- Invalid route exports found when prerendering with `ssr:fals
- Could not parse TypeScript
- React Router Vite plugin not found in Vite config
- Custom Vite manifest paths are not supported
AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12).
Data as JSON: /api/errors/c35f3f962d49791c.
Report an issue: GitHub.