withastro/astro · error · TypeError

Missing parameter: ${part.content}

Error message

Missing parameter: ${part.content}

What it means

getParameter() in generator.ts threw a TypeError because a required dynamic route parameter was missing from the params object. For non-spread dynamic segments, params[name] must be defined; rest segments fall back to '' but plain dynamic segments do not, so an undefined value is a hard error during URL generation.

Source

Thrown at packages/astro/src/core/routing/generator.ts:28

function sanitizeParams(params: Record<string, string | number>): Record<string, string | number> {
	return Object.fromEntries(
		Object.entries(params).map(([key, value]) => {
			if (typeof value === 'string') {
				return [key, value.normalize().replace(/#/g, '%23').replace(/\?/g, '%3F')];
			}
			return [key, value];
		}),
	);
}

function getParameter(part: RoutePart, params: Record<string, string | number>): string | number {
	if (part.spread) {
		return params[part.content.slice(3)] ?? '';
	}

	if (part.dynamic) {
		if (params[part.content] === undefined) {
			throw new TypeError(`Missing parameter: ${part.content}`);
		}

		return params[part.content];
	}

	return part.content
		.normalize()
		.replace(/\?/g, '%3F')
		.replace(/#/g, '%23')
		.replace(/%5B/g, '[')
		.replace(/%5D/g, ']');
}

function getSegment(segment: RoutePart[], params: Record<string, string | number>): string {
	const segmentPath = segment.map((part) => getParameter(part, params)).join('');

	return segmentPath ? collapseDuplicateLeadingSlashes('/' + segmentPath) : '';
}

View on GitHub (pinned to d081033d5f)

Solutions

  1. Provide every dynamic (non-rest) param as a defined string in the params object.
  2. In getStaticPaths(), make sure each entry's params includes all bracketed segment names.
  3. If a param should be optional, use a rest segment [...name] which tolerates absence.

Example fix

// before — route /[id]/[section]
export async function getStaticPaths() {
  return [{ params: { id: '1' } }]; // section missing
}

// after
export async function getStaticPaths() {
  return [{ params: { id: '1', section: 'intro' } }];
}
Defensive patterns

Strategy: validation

Validate before calling

function hasAllDynamicParams(params: Record<string, string>, segmentNames: string[]): boolean {
  return segmentNames.every(name => params[name] !== undefined);
}
// before generating a route, assert all dynamic segment names are present

Type guard

function hasRequiredParams(params: Record<string, unknown>, required: string[]): params is Record<string, string> {
  return required.every(k => typeof params[k] === 'string');
}

Try / catch

try {
  generateRoute(route, params);
} catch (e) {
  if (e instanceof TypeError && /Missing parameter/.test(e.message)) {
    // backfill or skip this entry
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the route generator with an incomplete params object (e.g. generateRoute({ id: '1' }) for /[id]/[section]); a getStaticPaths entry omitting a param; programmatic route generation missing a key.

Common situations: Returning getStaticPaths entries that omit one param; refactoring a route to add a segment without updating all param producers; downstream code calling the generator directly.

Related errors


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