expo/expo · error · Error
Internal error: Route not found for "${filePath}" while coll
Error message
Internal error: Route not found for "${filePath}" while collecting static export paths. What it means
Thrown deep in the static-export path collector when a resolved `filePath` cannot be matched to a `route` node. The comment explicitly says 'This should never happen', so this is a defensive guard against an internal invariant violation in Expo Router's manifest resolution. A plain `Error` is thrown, naming the unresolved `filePath`.
Source
Thrown at packages/@expo/cli/src/export/exportStaticAsync.ts:558
let filePath = baseUrl + leaf;
if (leaf === '') {
filePath =
baseUrl === ''
? 'index'
: baseUrl.endsWith('/')
? baseUrl + 'index'
: baseUrl.slice(0, -1);
} else if (
// If the path is a collection of group segments leading to an index route, append `/index`.
stripGroupSegmentsFromPath(filePath) === ''
) {
filePath += '/index';
}
// This should never happen, the type of `string | object` originally comes from React Navigation.
if (!route) {
throw new Error(
`Internal error: Route not found for "${filePath}" while collecting static export paths.`
);
}
if (includeGroupVariations) {
// TODO: Dedupe requests for alias routes.
addOptionalGroups(filePath, route);
} else {
htmlFiles.add({
filePath,
route,
});
}
} else if (typeof value === 'object' && value?.screens) {
// The __root slot has no path.
const newPath = value.path ? baseUrl + value.path + '/' : baseUrl;
traverseScreens(value.screens, value._route ?? null, newPath);
}View on GitHub (pinned to b09195aac2)
Solutions
- Treat this as a bug: note the `filePath` and your router layout, then check the Expo Router issue tracker / upgrade guide.
- Simplify the route tree (flatten groups, remove unused aliases) to find the structure that triggers the mismatch.
- Upgrade `expo-router` and `@expo/cli` to the latest patch — this is the kind of guard that gets fixed across releases.
- As a workaround, restructure the offending route so its path resolves without optional-group stitching.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await collectStaticExportPaths(...);
} catch (e) {
if (e instanceof Error && /Internal error: Route not found/.test(e.message)) {
// surface the filePath; this is an invariant bug — simplify the route tree and report upstream
}
throw e;
} Prevention
- Keep router layouts simple; avoid deeply nested optional groups and unusual aliases.
- Re-run exports after upgrading `expo-router` and `@expo/cli` — invariant fixes land in patches.
- If it reproduces, minimise the route tree to find the offending structure and file an issue with `filePath`.
When it happens
Trigger: An internal mismatch between the Router manifest's route nodes and the collected file paths — e.g. a group route, alias, or optional-group edge case the path collector did not account for. Triggered by unusual route layouts, deeply nested optional groups, or custom aliases combined with SSG.
Common situations: Exotic router configurations (many nested groups, aliases), upgrading Expo Router across versions where manifest shape changed, beta/unstable router features, or generated/typed routes that drift from the file tree.
Related errors
- Failed to statically export route: ${pathname}
- --no-ssg can only be used with `web.output: server`
- Failed to write generated server origin to app.json because
- JSON output of server deployment command are not in the expe
- --output-dir cannot be the same as the project directory.
AI-assisted analysis of expo/expo@b09195aac2 (2026-08-12).
Data as JSON: /api/errors/1bb699a435b4a979.
Report an issue: GitHub.