remix-run/react-router · error
Route config in "${routeConfigFile}" is invalid.
Error message
Route config in "${routeConfigFile}" is invalid. What it means
Importing or validating `routes.ts` threw: either the Vite-runner import failed (syntax error, unresolvable import, top-level throw) or `validateRouteConfig` rejected the shape. When Vite supplies `error.loc`/`error.frame`, the message includes a `file:line:column` pointer and the annotated code frame, so the exact spot in the route config is shown beneath the header.
Source
Thrown at packages/react-router-dev/config/config.ts:675
});
if (!result.valid) {
return err(result.message);
}
// Nest the route config under the resolved root route
routeConfig = [
{
id: "root",
path: "",
file: Path.relative(appDirectory, rootRouteFile),
children: result.routeConfig,
},
];
routes = configRoutesToRouteManifest(appDirectory, routeConfig);
} catch (error: any) {
return err(
[
colors.red(`Route config in "${routeConfigFile}" is invalid.`),
"",
error.loc?.file && error.loc?.column && error.frame
? [
Path.relative(appDirectory, error.loc.file) +
":" +
error.loc.line +
":" +
error.loc.column,
error.frame.trim?.(),
]
: error.stack,
]
.flat()
.join("\n"),
);
}View on GitHub (pinned to 6beaca3952)
Solutions
- Read the `file:line:column` and frame embedded in the error output — it points at the failing expression in the route config.
- Fix the import/path/typo it identifies (missing module, bad file extension, wrong relative path).
- Confirm the default export is a flat array of route config entries and `satisfies RouteConfig` typechecks.
- Run `pnpm run typecheck` (or `tsc`) to catch type-level mistakes in `routes.ts`.
Example fix
// before: app/routes.ts
import { route } from "@react-router/dev/routes";
export default [
route("about", "./abuot.tsx"), // typo -> import fails, "Route config ... is invalid"
];
// after
import { route } from "@react-router/dev/routes";
export default [
route("about", "./about.tsx"),
] satisfies RouteConfig; Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast on broken route file references before building
import fs from "node:fs";
import path from "node:path";
for (const entry of routeConfigEntries) {
const file = path.join("app", entry.file);
if (!fs.existsSync(file)) {
throw new Error(`Route config references missing file: ${entry.file}`);
}
} Type guard
function isRouteConfig(v: unknown): v is RouteConfigEntry[] {
return Array.isArray(v) && v.every((e) => typeof e?.file === "string");
} Try / catch
try {
const routesMod = await import("./app/routes.ts");
const entries = routesMod.default;
if (!Array.isArray(entries)) throw new Error("routes.ts default export must be an array");
} catch (e: any) {
if (e.loc?.file) {
console.error(`${path.relative(process.cwd(), e.loc.file)}:${e.loc.line}:${e.loc.column}`);
console.error(e.frame?.trim());
}
process.exit(1);
} Prevention
- End routes.ts with `satisfies RouteConfig` so TypeScript flags bad entries and paths.
- Run typecheck in CI to catch route-file typos before the build.
- After renaming/moving route files, grep routes.ts for stale paths.
When it happens
Trigger: A broken import in `app/routes.ts` (module not found); exporting a default that is not a valid `RouteConfig` array (e.g. an object or undefined); a helper like a custom `flatRoutes` call throwing; referencing a route file path that fails resolution inside the config.
Common situations: Renaming/moving route files without updating `routes.ts`; typos in `route("about", "./about.tssx")`; a route config helper that reads the filesystem and throws on unexpected structure; TS features in `routes.ts` not supported by the loader after a Vite upgrade.
Related errors
- The "serverBundles" function must only return strings contai
- The `prerender`/`prerender.paths` config must be a boolean,
- Could not find a root route module in the app directory as "
- Route config file not found at "${routeConfigDisplayPath}".
- React Router Vite plugin not found in Vite config
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/88e4110003389dd4.
Report an issue: GitHub.