Astro reports “Invalid value returned by a route from getStaticPaths()” when one of the objects you return has a params value that isn’t an object. Each route must look like { params: { slug: 'my-post' } }. Returning { params: 'my-post' }, an array, or undefined triggers this error. The full message says: “Invalid params value returned by a route from getStaticPaths(). Expected an object,” followed by what it received.
Key Takeaways
paramsmust be an object whose keys match the brackets in the file name.- Values must be strings (or
undefinedfor an optional rest param).- Pass extra data through
props, notparams.- When mapping data, check you’re not returning the raw item by accident.
What a valid return value looks like
// src/pages/blog/[slug].astro
export async function getStaticPaths() {
return [
{ params: { slug: 'first-post' }, props: { title: 'First post' } },
{ params: { slug: 'second-post' }, props: { title: 'Second post' } },
];
}
For several parameters, as in src/pages/[lang]/[slug].astro:
return [{ params: { lang: 'en', slug: 'pricing' } }];
For a rest parameter, as in src/pages/docs/[...path].astro:
return [
{ params: { path: 'getting-started/install' } },
{ params: { path: undefined } }, // serves /docs/
];
Typical mistakes
Returning a string as params
// Wrong
return posts.map((post) => ({ params: post.id }));
// Right
return posts.map((post) => ({ params: { slug: post.id } }));
Returning the item instead of a route
// Wrong: each element is a post object, not { params }
return posts;
Map to { params, props } first.
Nesting params in props by mistake
// Wrong
return posts.map((post) => ({ props: { params: { slug: post.id } } }));
Related errors
If the object exists but has no keys, Astro shows Missing params property on getStaticPaths() route. If params are valid but a URL still doesn’t resolve, see No static path found.
Type it to catch this earlier
Use the GetStaticPaths type so your editor flags bad shapes before you build:
import type { GetStaticPaths } from 'astro';
export const getStaticPaths = (async () => {
const posts = await getCollection('blog');
return posts.map((post) => ({ params: { slug: post.id }, props: { post } }));
}) satisfies GetStaticPaths;
Run npx astro check to type-check every page. The Astro routing guide explains dynamic routes fully, and the routing reference documents every field.
FAQ
Can params values be numbers in Astro?
No. They must be strings. Convert with String(value).
Where should I put data the page needs?
In props. The page reads it from Astro.props, which avoids a second lookup.