withastro/astro · error · Error

Invalid route ${file} — parameters must be separated

Error message

Invalid route ${file} — parameters must be separated

What it means

validateSegment() rejected a route segment where dynamic parameters are adjacent without a separator — the pattern '][' appears inside a single segment. Astro requires parameters to be separated by static text (e.g. [id]-[lang]); back-to-back brackets like [id][lang] are ambiguous and disallowed. Thrown as a plain Error during route parsing.

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 d081033d5f)

Solutions

  1. Insert a separator between the params: [id]-[lang].astro, [id]_[lang].astro, or [id]/[lang].astro (separate segments).
  2. Use a single combined param and split it in code if you truly need both values in one segment.
  3. Confirm brackets are balanced and no stray '][' remains.

Example fix

// before — src/pages/[id][lang].astro

// after — src/pages/[id]-[lang].astro
Defensive patterns

Strategy: validation

Validate before calling

function segmentsAreSeparated(segment: string): boolean {
  return !segment.includes('][');
}
// validate route segments before parsing

Type guard

function isValidSegment(segment: string): boolean {
  return !segment.includes('][') &&
    countOccurrences('[', segment) === countOccurrences(']', segment);
}

Prevention

When it happens

Trigger: A filename like src/pages/[id][lang].astro; multiple params jammed into one segment with no separating characters; copy-paste errors concatenating param brackets.

Common situations: Trying to combine two params in one segment; misunderstanding that each [param] needs delimiters; refactor mistakes when splitting a static segment into params.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/7b7fe711b1ced7e4. Report an issue: GitHub.