{"record":{"id":"fd5df7fe3435c567","repo":"withastro/astro","slug":"the-route-a-route-is-defined-in-both-a-com-fd5df7","errorCode":null,"errorMessage":"The route \"${a.route}\" is defined in both \"${a.component}\" and \"${b.component}\" using SSR mode. A dynamic SSR route cannot be defined more than once.","messagePattern":"The route \"(.+?)\" is defined in both \"(.+?)\" and \"(.+?)\" using SSR mode\\. A dynamic SSR route cannot be defined more than once\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/astro/src/core/routing/create-manifest.ts","lineNumber":685,"sourceCode":"\t\treturn;\n\t}\n\n\t// Routes have the same number of segments, can use either.\n\tconst segmentCount = a.segments.length;\n\n\tfor (let index = 0; index < segmentCount; index++) {\n\t\tconst segmentA = a.segments[index];\n\t\tconst segmentB = b.segments[index];\n\n\t\tif (!isSemanticallyEqualSegment(segmentA, segmentB)) {\n\t\t\t// If any segment is not semantically equal between the routes\n\t\t\t// it is not certain that the routes collide.\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Both routes are guaranteed to collide such that one will never be matched.\n\tlogger.warn(\n\t\t'router',\n\t\t`The route \"${a.route}\" is defined in both \"${a.component}\" and \"${b.component}\" using SSR mode. A dynamic SSR route cannot be defined more than once.`,\n\t);\n\tlogger.warn('router', 'A collision will result in a hard error in following versions of Astro.');\n}\n\n/**\n * Create a full route manifest from filesystem and injected routes.\n */\nexport async function createRoutesList(\n\tparams: CreateRouteManifestParams,\n\tlogger: AstroLogger,\n\t{\n\t\tdev = false,\n\t}: {\n\t\tdev?: boolean;\n\t} = {},\n): Promise<RoutesList> {","sourceCodeStart":667,"sourceCodeEnd":703,"githubUrl":"https://github.com/withastro/astro/blob/e294953aa8aadd98d5be92e60a03037b05dbdfd4/packages/astro/src/core/routing/create-manifest.ts#L667-L703","documentation":"For server-rendered routes, validateCollisions compares dynamic patterns segment-by-segment with semantic equality: [id] and [slug] at the same position are equivalent because both match any single value. When two files yield segment-equal dynamic routes in SSR mode, only one can match, so Astro warns (domain 'router') that a dynamic SSR route cannot be defined more than once.","triggerScenarios":"Two non-prerendered routes whose patterns differ only in parameter names at the same positions — e.g. pages/blog/[slug].astro next to pages/blog/[id].astro, or [...slug] vs [...path] at the same spot — after the earlier static and prerender short-circuit checks did not return.","commonSituations":"Copy-pasting a dynamic page and renaming the parameter; merging route folders during a refactor; an injected admin route colliding semantically with a user route in output 'server'.","solutions":["Keep exactly one file per dynamic pattern — delete or rename the duplicate","Differentiate the routes with distinct static segments (e.g. /blog/[slug] vs /news/[id])","If both behaviors are needed, merge into one route that branches internally on the parameter value"],"exampleFix":"# before — semantically identical in SSR\nsrc/pages/shop/[slug].astro\nsrc/pages/shop/[id].astro\n\n# after\nsrc/pages/shop/[slug].astro  # keep one; merge any extra logic into it","handlingStrategy":"validation","validationCode":"import { readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nfunction normalize(dir, prefix = '') {\n  const out = [];\n  for (const e of readdirSync(dir, { withFileTypes: true })) {\n    const seg = e.name.replace(/\\.(astro|js|ts)$/, '').replace(/\\[.+?\\]/g, '[param]');\n    const p = join(dir, e.name);\n    if (e.isDirectory()) out.push(...normalize(p, prefix + '/' + seg));\n    else out.push(prefix + '/' + seg);\n  }\n  return out;\n}\nconst all = normalize('src/pages');\nconst dupes = all.filter((p, i) => all.indexOf(p) !== i);\nif (dupes.length) throw new Error('semantically duplicate dynamic routes: ' + dupes.join(', '));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use one consistent parameter name per route position across the project","When copying a dynamic page, change a static segment, not just the param name","Check injected routes for patterns that differ from filesystem routes only in param names"],"tags":["routing","duplicate-route","ssr","dynamic-routes","rest-params"],"backgroundTag":"duplicate-route","analyzedSha":"e294953aa8aadd98d5be92e60a03037b05dbdfd4","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}