withastro/astro · error · AstroError
GetStaticPathsExpectedParams
GetStaticPathsExpectedParams
Error message
Missing or empty required `params` property on `getStaticPaths()` route.
What it means
Each getStaticPaths() entry must carry a non-empty params object — it is what Astro feeds into route pattern generation. validateGetStaticPathsResult throws GetStaticPathsExpectedParams when an entry's params is undefined, null, or an object with zero keys. An entry without params cannot produce any URL, and an empty params object on a dynamic route would emit a broken path.
Solutions
- Add a params object with a value for every dynamic segment in the filename: { params: { slug }, props: { post } }.
- Check for typos: the key must be exactly params (plural), and its keys must match the [param] names in the route file.
- Filter out items whose param value is missing before returning: items.filter(i => i.slug).map(...).
Example fix
// before
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map((post) => ({ props: { post } })); // no params
}
// after
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map((post) => ({ params: { slug: post.slug }, props: { post } }));
} Defensive patterns
Strategy: type-guard
Validate before calling
const entries = items.map((i) => ({ params: { slug: i.slug }, props: { i } }));
const valid = entries.every((e) => e.params && Object.keys(e.params).length > 0);
if (!valid) throw new Error('every getStaticPaths entry needs non-empty params');
return entries; Type guard
function hasParams(
e: unknown,
): e is { params: Record<string, string | undefined> } {
return (
typeof e === 'object' &&
e !== null &&
'params' in e &&
typeof (e as { params: unknown }).params === 'object' &&
(e as { params: object }).params !== null &&
Object.keys((e as { params: object }).params).length > 0
);
} Prevention
- params keys must exactly match the [names] in the filename; params must be non-empty.
- Filter out items with missing slugs before mapping them into entries.
- Copy the { params, props } entry shape verbatim; do not rename params.
When it happens
Trigger: Returning [{ props: { post } }] and forgetting params; destructuring params from the wrong variable so it is undefined ({ params: post.params } where post.params does not exist); returning entries like { params: {} }; a typo such as { param: { slug } } (singular).
Common situations: Entries built from props-only data; content collections where the developer passes props but assumes Astro infers params; copy-paste of an entry template with params deleted; keys computed dynamically that end up empty for some items.
Related errors
- InvalidGetStaticPathsEntry
- InvalidGetStaticPathsReturn
- getStaticPaths() ignored in dynamic page
- GetStaticPathsRequired
- Astro.generator inside getStaticPaths is deprecated and…
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/ce91d7502e6bb055.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/core/routing/validation.ts:52
});
}
result.forEach((pathObject) => {
if ((typeof pathObject === 'object' && Array.isArray(pathObject)) || pathObject === null) {
throw new AstroError({
...AstroErrorData.InvalidGetStaticPathsEntry,
message: AstroErrorData.InvalidGetStaticPathsEntry.message(
Array.isArray(pathObject) ? 'array' : typeof pathObject,
),
});
}
if (
pathObject.params === undefined ||
pathObject.params === null ||
(pathObject.params && Object.keys(pathObject.params).length === 0)
) {
throw new AstroError({
...AstroErrorData.GetStaticPathsExpectedParams,
location: {
file: route.component,
},
});
}
});
}
View on GitHub (pinned to 52e6c34790)