withastro/astro · error · Error
Invalid route — parameters must be separated
Error message
Invalid route ${file} — parameters must be separated What it means
Astro compiles pages/ filenames into route patterns where each [param] is a placeholder. Two parameter groups placed directly next to each other, like [id][slug], are rejected by validateSegment because without a literal separator Astro cannot build an unambiguous matching regex (where does id end and slug begin?). Only the adjacent-bracket pattern '][' triggers this specific message.
Solutions
- Put a literal separator between the params: rename [id][slug].astro to [id]-[slug].astro (matches /123-hello).
- Or make them real path segments: move to src/pages/[id]/[slug].astro (matches /123/hello).
Example fix
// before src/pages/[lang][slug].astro // throws: parameters must be separated // after src/pages/[lang]-[slug].astro // matches /en-hello-world
Defensive patterns
Strategy: validation
Validate before calling
// run in CI or a predev/prebuild script over your pages directory
import { glob } from 'node:fs/promises';
for await (const file of glob('src/pages/**/*')) {
const segment = file.split('/').pop()!;
if (segment.includes('][')) {
throw new Error(`Route file ${file} has adjacent [param][param] segments`);
}
} Prevention
- One bracket group per literal chunk; separate params with '-' or '/'.
- Add a lint/CI check on filenames under pages/ before astro build runs.
- When scaffolding routes from a URL list, derive filenames programmatically instead of by hand.
When it happens
Trigger: Creating a file in src/pages (or src/pages/api, or a custom pages dir) whose name or directory segment contains two bracket groups with nothing between them: src/pages/[id][slug].astro, src/pages/api/[a][b].json.ts, or two rest params [...a][...b].astro.
Common situations: Scaffolding nested-resource URLs like /users/:id/posts/:slug in one filename; renaming files quickly with an editor; porting :id:slug-style routes from other frameworks; typo when splitting an existing dynamic route.
Related errors
- Invalid route — brackets are unbalanced
- Invalid route — rest parameter must be a standalone segment
- Invalid route — parameter name must match /^[a-zA-Z0-9_$]+$/
- getStaticPaths() ignored in dynamic page
- GetStaticPathsRequired
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/7b7fe711b1ced7e4.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/core/routing/segment.ts:5
export function validateSegment(segment: string, file = '') {
if (!file) file = segment;
if (segment.includes('][')) {
throw new Error(`Invalid route ${file} \u2014 parameters must be separated`);
}
if (countOccurrences('[', segment) !== countOccurrences(']', segment)) {
throw new Error(`Invalid route ${file} \u2014 brackets are unbalanced`);
}
if (
(/.+\[\.\.\.[^\]]+\]/.test(segment) || /\[\.\.\.[^\]]+\].+/.test(segment)) &&
file.endsWith('.astro')
) {
throw new Error(`Invalid route ${file} \u2014 rest parameter must be a standalone segment`);
}
}
function countOccurrences(needle: string, haystack: string) {
let count = 0;
for (const hay of haystack) {
if (hay === needle) count += 1;
}
return count;View on GitHub (pinned to 52e6c34790)