withastro/astro · error · AstroError
PageNumberParamNotFound
PageNumberParamNotFound
Error message
[paginate()] page number param `${paramName}` not found in your filepath. What it means
Thrown by paginate() when the route's filename does not contain a 'page' dynamic segment. paginate() generates URLs for each page by substituting a param literally named 'page', so the filepath must declare [page] or [...page] for it to inject the number.
Source
Thrown at packages/astro/src/core/render/paginate.ts:36
): (...args: Parameters<PaginateFunction>) => ReturnType<PaginateFunction> {
return function paginateUtility(
data: readonly any[],
args: PaginateOptions<Props, Params> = {},
): ReturnType<PaginateFunction> {
const generate = getRouteGenerator(routeMatch.segments, trailingSlash);
let { pageSize: _pageSize, params: _params, props: _props, format: _format } = args;
const pageSize = _pageSize || 10;
const paramName = 'page';
const additionalParams = _params || {};
const additionalProps = _props || {};
const formatUrl = _format || ((url: string) => url);
let includesFirstPageNumber: boolean;
if (routeMatch.params.includes(`...${paramName}`)) {
includesFirstPageNumber = false;
} else if (routeMatch.params.includes(`${paramName}`)) {
includesFirstPageNumber = true;
} else {
throw new AstroError({
...AstroErrorData.PageNumberParamNotFound,
message: AstroErrorData.PageNumberParamNotFound.message(paramName),
});
}
const lastPage = Math.max(1, Math.ceil(data.length / pageSize));
const result = [...Array(lastPage).keys()].map((num) => {
const pageNum = num + 1;
const start = pageSize === Number.POSITIVE_INFINITY ? 0 : (pageNum - 1) * pageSize; // currentPage is 1-indexed
const end = Math.min(start + pageSize, data.length);
const params = {
...additionalParams,
[paramName]: includesFirstPageNumber || pageNum > 1 ? String(pageNum) : undefined,
};
const current = formatUrl(addRouteBase(generate({ ...params }), base));
const next =
pageNum === lastPage
? undefinedView on GitHub (pinned to d081033d5f)
Solutions
- Rename the route file so it contains [page], e.g. src/pages/blog/[page].astro.
- For catch-all pagination use [...page].astro.
- Verify routeMatch.params includes 'page' or '...page' before relying on paginate().
Example fix
// before — file: src/pages/blog.astro
export async function getStaticPaths() {
return paginate(getCollection('posts'), { pageSize: 10 });
}
// after — rename file to src/pages/blog/[page].astro
export async function getStaticPaths() {
return paginate(getCollection('posts'), { pageSize: 10 });
} Defensive patterns
Strategy: validation
Validate before calling
const PAGE_PARAM = 'page';
function routeHasPageParam(params: string[]): boolean {
return params.includes(PAGE_PARAM) || params.includes(`...${PAGE_PARAM}`);
}
// only call paginate() when this returns true Prevention
- Name paginated routes [page].astro or [...page].astro by convention.
- Add a lint/code-review check that paginate() is only called in files containing the [page] segment.
- Remember paginate() hardcodes the 'page' param name — it is not configurable.
When it happens
Trigger: Calling paginate() inside getStaticPaths() of a file named e.g. [id].astro or blog.astro that has no [page] segment; renaming the file but forgetting to update the param; using a custom paramName is not supported — paginate() hardcodes 'page'.
Common situations: Following a pagination tutorial on a route whose filename lacks the [page] param; converting a non-paginated route to paginated without renaming the file; expecting paginate() to work on [...slug].astro rest routes.
Related errors
- NoMatchingStaticPathFound
- Invalid route ${file} — parameter name must match /^[a-zA-Z0
- Missing parameter: ${part.content}
- GetStaticPathsInvalidRouteParam
- Invalid route ${file} — parameter name must match /^[a-zA-Z0
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/6eef103dbc8fea50.
Report an issue: GitHub.