remix-run/react-router · error · Error
React Router presets must have a `name` property defined.
Error message
React Router presets must have a `name` property defined.
What it means
While resolving react-router.config.ts, every entry of the presets array must have a name property (presets are identified by name when merged and reported). During config resolution the loader maps over presets and throws on the first entry lacking name, which fails the dev server or build startup.
Solutions
- Add a name to every entry in the presets array
- Scan the array for accidental empty objects or stray trailing entries
- Restart the dev server after saving react-router.config.ts
Example fix
// before: react-router.config.ts
export default {
presets: [
{ reactRouterConfig: async () => ({ ssr: true }) },
],
};
// after
export default {
presets: [
{
name: "ssr-on",
reactRouterConfig: async () => ({ ssr: true }),
},
],
}; Defensive patterns
Strategy: type-guard
Validate before calling
import type { Preset, ReactRouterConfig } from "@react-router/dev";
function isNamedPreset(p: Preset): p is Preset & { name: string } {
return typeof p.name === "string" && p.name.length > 0;
}
export default {
presets: myPresets.every(isNamedPreset) ? myPresets : (() => {
throw new Error("Every preset needs a non-empty `name`");
})(),
} satisfies ReactRouterConfig; Type guard
interface PresetLike {
name?: unknown;
reactRouterConfig?: unknown;
}
function isNamedPreset(p: PresetLike): p is { name: string } & PresetLike {
return typeof p.name === "string" && p.name.length > 0;
} Prevention
- Type react-router.config.ts properly (satisfies ReactRouterConfig) so TypeScript flags missing name
- Start from the documented preset example which includes name
- Give presets stable, descriptive names — they identify the preset in merged output
When it happens
Trigger: Writing presets: [{}] (empty object), or presets: [{ reactRouterConfig: ... }] with the config function but no name; JS configs or `any` casts bypassing the TypeScript Preset type that would normally flag it.
Common situations: Adding a first preset to react-router.config.ts; copy-pasting preset examples that omit name; refactors that rename or drop the name field.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Could not find package.json in
- Route config file not found at
- Could not find a root route module in the app directory
- Could not find a root route module in the app directory as
- Could not find the routes directory
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/f64d40a1a05d8124.
Report an issue: GitHub.
Appendix: source
Thrown at packages/react-router-dev/config/config.ts:494
if (validateConfig) {
const error = validateConfig(reactRouterUserConfig);
if (error) {
return err(error);
}
}
} catch (error) {
return err(`Error loading ${reactRouterConfigFile}: ${error}`);
}
}
// Prevent mutations to the user config
reactRouterUserConfig = deepFreeze(cloneDeep(reactRouterUserConfig));
let presets: ReactRouterConfig[] = (
await Promise.all(
(reactRouterUserConfig.presets ?? []).map(async (preset) => {
if (!preset.name) {
throw new Error(
"React Router presets must have a `name` property defined.",
);
}
if (!preset.reactRouterConfig) {
return null;
}
let configPreset: ReactRouterConfig = omit(
await preset.reactRouterConfig({ reactRouterUserConfig }),
excludedConfigPresetKeys,
);
return configPreset;
}),
)
).filter(function isNotNull<T>(value: T | null): value is T {
return value !== null;View on GitHub (pinned to 6beaca3952)