{"record":{"id":"595bf93b7ef86421","repo":"remix-run/react-router","slug":"unable-to-define-routes-with-duplicate-route-id","errorCode":null,"errorMessage":"Unable to define routes with duplicate route id: \"${id}\"","messagePattern":"Unable to define routes with duplicate route id: \"(.+?)\"","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router-dev/config/routes.ts","lineNumber":377,"sourceCode":"  routes: RouteConfigEntry[],\n): RouteManifest {\n  let routeManifest: RouteManifest = {};\n\n  function walk(route: RouteConfigEntry, parentId?: string) {\n    let id = route.id || createRouteId(route.file);\n    let manifestItem: RouteManifestEntry = {\n      id,\n      parentId,\n      file: Path.isAbsolute(route.file)\n        ? Path.relative(appDirectory, route.file)\n        : route.file,\n      path: route.path,\n      index: route.index,\n      caseSensitive: route.caseSensitive,\n    };\n\n    if (routeManifest.hasOwnProperty(id)) {\n      throw new Error(\n        `Unable to define routes with duplicate route id: \"${id}\"`,\n      );\n    }\n    routeManifest[id] = manifestItem;\n\n    if (route.children) {\n      for (let child of route.children) {\n        walk(child, id);\n      }\n    }\n  }\n\n  for (let route of routes) {\n    walk(route);\n  }\n\n  return routeManifest;\n}","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router-dev/config/routes.ts#L359-L395","documentation":"Thrown by configRoutesToRouteManifest() while walking the route config tree when a route's computed id already exists in routeManifest. The id is route.id if provided, otherwise createRouteId(route.file) (the file path with extension stripped and path normalized). Because flatRoutes() derives ids from file paths, two route files resolving to the same normalized id, an explicit duplicate route.id, or two routes pointing at the same file all collide.","triggerScenarios":"Defining two routes with the same id via route({ id: 'x', ... }); two route files whose paths normalize identically (e.g. routes/players.tsx and routes/players/index.tsx both collapsing to the same id); manually duplicating an entry in routes.ts that points at the same file; using route() and index() helpers against the same file.","commonSituations":"Hand-writing routes.ts and reusing an id; file-system routing edge case where a layout and a child produce the same id; refactoring that moved a route file without updating routes.ts leaving a stale duplicate; case-insensitive filesystem masking two paths that normalize differently.","solutions":["Search routes.ts and your app/routes for the quoted id in the error; remove or rename the duplicate entry.","If using flatRoutes(), check for two files that normalize to the same id (e.g. parent.tsx vs parent/index.tsx) and rename one.","Give each manual route a unique id, or omit id entirely so it derives from file.","Ensure each route() helper call references a distinct file.","Run the build with a clean routes.ts (comment out halves) to bisect which pair collides."],"exampleFix":"// before (routes.ts) -- duplicate id\nexport default [\n  route('about', './about.tsx', { id: 'page' }),\n  route('contact', './contact.tsx', { id: 'page' }),\n];\n// after -- unique ids (or omit id)\nexport default [\n  route('about', './about.tsx'),\n  route('contact', './contact.tsx'),\n];","handlingStrategy":"validation","validationCode":"// Walk routes.ts and detect duplicate ids before build\nfunction findDuplicateRouteIds(routes: any[]): string[] {\n  const ids = new Set<string>();\n  const dupes: string[] = [];\n  function walk(r: any) {\n    const id = r.id ?? r.file.replace(/\\.[tj]sx?$/, '');\n    if (ids.has(id)) dupes.push(id); else ids.add(id);\n    (r.children ?? []).forEach(walk);\n  }\n  routes.forEach(walk);\n  return dupes;\n}\nconst dupes = findDuplicateRouteIds(myRoutes);\nif (dupes.length) throw new Error('Duplicate route ids: ' + dupes.join(', '));","typeGuard":"function hasUniqueRouteIds(routes: any[]): boolean {\n  const seen = new Set<string>();\n  for (const r of routes) {\n    const id = r.id ?? r.file.replace(/\\.[tj]sx?$/, '');\n    if (seen.has(id)) return false;\n    seen.add(id);\n  }\n  return true;\n}","tryCatchPattern":null,"preventionTips":["Use flatRoutes() consistently to let ids derive from file paths deterministically.","When writing manual route() entries, omit id unless you need it, and never reuse one.","After renaming a route file, search routes.ts for stale references.","Add a pre-build check that asserts all route ids are unique."],"tags":["routes","config","routing","react-router-dev","framework-mode"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}