{"record":{"id":"4b12cdf7cc94b0c7","repo":"withastro/astro","slug":"the-route-a-route-is-defined-in-both-a-com","errorCode":null,"errorMessage":"The route \"${a.route}\" is defined in both \"${a.component}\" and \"${b.component}\". A static route cannot be defined more than once.","messagePattern":"The route \"(.+?)\" is defined in both \"(.+?)\" and \"(.+?)\"\\. A static 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":647,"sourceCode":"\ta: RouteData,\n\tb: RouteData,\n\t_config: AstroConfig,\n\tlogger: AstroLogger,\n) {\n\tif (a.type === 'fallback' || b.type === 'fallback') {\n\t\t// If either route is a fallback route, they don't collide.\n\t\t// Fallbacks are always added below other routes exactly to avoid collisions.\n\t\treturn;\n\t}\n\n\tif (\n\t\ta.route === b.route &&\n\t\ta.segments.every(isStaticSegment) &&\n\t\tb.segments.every(isStaticSegment)\n\t) {\n\t\t// If both routes are the same and completely static they are guaranteed to collide\n\t\t// such that one of them will never be matched.\n\t\tlogger.warn(\n\t\t\t'router',\n\t\t\t`The route \"${a.route}\" is defined in both \"${a.component}\" and \"${b.component}\". A static route cannot be defined more than once.`,\n\t\t);\n\t\tlogger.warn(\n\t\t\t'router',\n\t\t\t'A collision will result in a hard error in following versions of Astro.',\n\t\t);\n\t\treturn;\n\t}\n\n\tif (a.prerender || b.prerender) {\n\t\t// If either route is prerendered, it is impossible to know if they collide\n\t\t// at this stage because it depends on the parameters returned by `getStaticPaths`.\n\t\treturn;\n\t}\n\n\tif (a.segments.length !== b.segments.length) {\n\t\t// If the routes have different number of segments, they cannot perfectly overlap","sourceCodeStart":629,"sourceCodeEnd":665,"githubUrl":"https://github.com/withastro/astro/blob/e294953aa8aadd98d5be92e60a03037b05dbdfd4/packages/astro/src/core/routing/create-manifest.ts#L629-L665","documentation":"Two routes in the manifest resolve to the exact same fully-static pattern (every segment static, e.g. about.astro and about/index.astro). Only one can ever match, so Astro warns (domain 'router') that the route is defined in both files and that a static route cannot be defined more than once.","triggerScenarios":"Files under pages/ that normalize to the same URL: foo.astro plus foo/index.astro, index.astro plus index.md in one directory, or two injected static routes with the same pattern — and neither route being a fallback route.","commonSituations":"Adding index.md docs beside an existing .astro page; refactoring nested folder structures without deleting old files; copy-pasting a page under a new name; injected routes from integrations duplicating filesystem routes.","solutions":["Delete or rename one of the two colliding files/routes","Render markdown twins through a single dynamic route ([...slug].astro with content collections) instead of a duplicate static page","Audit integration injectRoute patterns against your filesystem routes"],"exampleFix":"# before — both normalize to /about\nsrc/pages/about.astro\nsrc/pages/about/index.astro\n\n# after\nsrc/pages/about/index.astro  # keep exactly one","handlingStrategy":"validation","validationCode":"import { readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nfunction patterns(dir, prefix = '') {\n  const out = [];\n  for (const e of readdirSync(dir, { withFileTypes: true })) {\n    const p = join(dir, e.name);\n    if (e.isDirectory()) out.push(...patterns(p, prefix + '/' + e.name));\n    else {\n      const base = e.name.replace(/\\.(astro|md|mdx|markdown)$/, '');\n      const seg = base === 'index' ? '' : '/' + base;\n      out.push((prefix + seg) || '/');\n    }\n  }\n  return out;\n}\nconst all = patterns('src/pages');\nconst dupes = all.filter((p, i) => all.indexOf(p) !== i);\nif (dupes.length) throw new Error('duplicate routes: ' + dupes.join(', '));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one convention for leaf pages (file.astro OR folder/index.astro) per project","Delete the old file in the same commit when restructuring routes","Run the duplicate-pattern check in CI before Astro turns collisions into errors"],"tags":["routing","duplicate-route","static","manifest"],"backgroundTag":"duplicate-route","analyzedSha":"e294953aa8aadd98d5be92e60a03037b05dbdfd4","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}