withastro/astro · error · TypeError
Missing parameter
Error message
Missing parameter: ${part.content} What it means
`getRouteGenerator` composes concrete paths from a params object: every dynamic (non-spread) route part must find a defined value in `params`, or it throws `TypeError: Missing parameter: <name>`. It is reached mainly through `stringifyParams`, which keys `getStaticPaths()` results — and note that `stringifyParams` drops `undefined` values before generating, so an undefined or omitted param for a dynamic segment lands here. Spread (`...rest`) params are optional and default to empty string.
Solutions
- Supply a concrete string for every dynamic segment named in the file (`[lang]/[slug]` needs both `lang` and `slug`)
- Check for typos between the bracket name in the filename and the keys in `params`
- Default or filter undefined values before returning: `params: { slug: post.slug ?? post.id }`
- Remember spread params (`[...rest]`) are the only optional ones
Example fix
// before — src/pages/blog/[lang]/[slug].astro
export async function getStaticPaths() {
return [{ params: { lang: 'en' } }]; // slug missing → TypeError
}
// after
return [{ params: { lang: 'en', slug: 'hello' } }]; Defensive patterns
Strategy: type-guard
Validate before calling
// Assert completeness before returning getStaticPaths entries
const required = ['lang', 'slug']; // names inside the file's brackets
const complete = paths.every((p) => hasAllParams(required, p.params));
if (!complete) throw new Error('getStaticPaths entry missing a dynamic param'); Type guard
// Every dynamic (non-spread) param must be a defined string
export function hasAllParams(required: string[], params: Record<string, unknown>): boolean {
return required.every((k) => typeof params[k] === 'string');
} Prevention
- Derive params from the same object graph that defines the route's data so keys can't drift
- Default or skip entries with optional values: `{ slug: item.slug ?? item.id }` or `.filter()`
- Only spread (`[...rest]`) params are optional — everything else in brackets must be provided
When it happens
Trigger: `getStaticPaths()` for `src/pages/blog/[lang]/[slug].astro` returning `[{ params: { lang: 'en' } }]` (slug missing); a typo'd key (`{ slugs: 'x' }` vs the file's `[slug]`); values that are `undefined` after filtering, e.g. `{ slug: post.slug }` where `post.slug` is undefined; consuming `generatePattern`-style utilities (e.g. sitemap or route-stringify helpers) with incomplete params.
Common situations: Optional CMS fields that sometimes yield undefined slugs; refactoring filenames without updating params keys; building path strings from partial objects in integrations.
Related errors
- GetStaticPathsInvalidRouteParam
- context.params don't contain any usable content in Astro.
- Error generating redirects
- Error generating routes
- getStaticPaths() ignored in dynamic page
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/a5d0fd21213ef705.
Report an issue: GitHub.
Appendix: 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 52e6c34790)