remix-run/remix · error · Error
Route module ${routesFile} must export a named "routes" valu
Error message
Route module ${routesFile} must export a named "routes" value. What it means
The route-map worker imports your app/routes.ts module and requires it to export a named `routes` value (the framework 3 config-based routing entry point). If the module has no `routes` export, the worker throws before parsing anything.
Source
Thrown at packages/cli/src/lib/load-route-map-worker.ts:30
setExitCode(1)
})
async function run(): Promise<void> {
let routesFile = process.argv[2]
if (typeof routesFile !== 'string' || routesFile.length === 0) {
throw new Error('Missing app/routes.ts path.')
}
let tree = await loadRawRouteTree(routesFile)
process.stdout.write(JSON.stringify(tree))
}
async function loadRawRouteTree(routesFile: string): Promise<RawRouteTreeNode[]> {
let routeModule: object = await import(pathToFileURL(routesFile).href)
if (!('routes' in routeModule)) {
throw new Error(`Route module ${routesFile} must export a named "routes" value.`)
}
return normalizeRouteGroup(routeModule.routes, [], new Map())
}
function normalizeRouteGroup(
value: unknown,
parentSegments: string[],
seen: Map<object, string>,
): RawRouteTreeNode[] {
if (!isPlainObject(value)) {
let location = parentSegments.length === 0 ? 'routes' : parentSegments.join('.')
throw new Error(`Invalid route map value at "${location}". Expected a nested route object.`)
}
let existingPath = seen.get(value)
let currentPath = parentSegments.length === 0 ? 'routes' : parentSegments.join('.')
if (existingPath != null) {View on GitHub (pinned to 9696913134)
Solutions
- Add a named `routes` export: `export let routes = {...}` in app/routes.ts
- If using an empty route set temporarily, export an empty object `export let routes = {}`
- Check for accidental `default` export and move it to a named `routes` export
Example fix
// before (app/routes.ts)
export default { root: '/' }
// after
export let routes = { root: '/' } Defensive patterns
Strategy: type-guard
Validate before calling
let mod = await import(pathToFileURL(routesPath).href)
if (!('routes' in mod)) throw new Error('app/routes.ts must export `routes`') Type guard
function hasRoutesExport(mod: object): mod is { routes: unknown } {
return 'routes' in mod
} Prevention
- Use `export let routes = {...}` in app/routes.ts
- Run `remix routes` after creating the file to catch mistakes early
- Avoid default exports in the route map module
When it happens
Trigger: app/routes.ts (or the configured route-map file) exports only `default`, only types, or nothing at all — e.g. `export default [{ path: '/' }]` instead of `export let routes = {...}`.
Common situations: Migrating from file-based routing or React Router style config and keeping a default export; leftover placeholder routes.ts created empty; typos like `export const route =` (singular).
Related errors
- RMX_ROUTE_MAP_LOADER_FAILED
- throw new AssertionError({ message, actual, expected, operat
- expect(received).toThrow() requires a function (got ${typeof
- expected promise to resolve, but it rejected with: ${stringi
- expected promise to reject, but it resolved with: ${stringif
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/d7ef9e408d17cae8.
Report an issue: GitHub.