withastro/astro · error · AstroError
PageNumberParamNotFound
PageNumberParamNotFound
Error message
[paginate()] page number param `${paramName}` not found in your filepath. What it means
`paginate()` is the helper passed to `getStaticPaths()` for pagination; it generates one entry per page using a fixed param named `page`. Each generated path needs somewhere to put that number, so the route's params must contain either `page` (via a `[page].astro` file) or `...page` (via `[...page].astro`, which folds page 1 into the base path). If the matched route declares neither, Astro throws `PageNumberParamNotFound`.
Solutions
- Rename the file to include the param: `src/pages/products/[page].astro`
- Use the spread form `src/pages/products/[...page].astro` when page 1 should live at the base URL `/products`
- Spell the param exactly `page` — `paginate()` does not accept a custom param name
Example fix
# before src/pages/products.astro # exports getStaticPaths using paginate() # after src/pages/products/[page].astro # param must be named exactly `page` # (or products/[...page].astro so page 1 lives at /products)
Defensive patterns
Strategy: validation
Validate before calling
# CI guard: paginate() must live in a file whose name contains [page] or [...page]
grep -rl 'paginate(' src/pages --include='*.astro' | grep -v '\[\.\.\.page\]\|\[page\]' && { echo 'paginate() used without a [page] param'; exit 1; } || true Prevention
- Name paginated routes `[page].astro` (or `[...page].astro`) before writing getStaticPaths
- The param name is fixed to `page` — never `[p]`, `[pagenum]`, or `[...pages]`
- Add the grep guard above to CI so renames fail fast
When it happens
Trigger: Calling `paginate(data)` inside `getStaticPaths()` of a page whose filename has no page param, e.g. `src/pages/products.astro`; misspelling the param in the filename (`[...pages].astro`, `[pagenum].astro`) so the literal `page`/`...page` param never exists; restructuring pages and dropping the `[page]` segment.
Common situations: First attempt at paginating a listing page before renaming the file; renaming `[page].astro` during a refactor and forgetting getStaticPaths still paginates; copy-pasting a paginated component into a non-dynamic route.
Related errors
- GetStaticPathsInvalidRouteParam
- Internal Warning: route cache overwritten.
- Invalid route — parameter name must match /^[a-zA-Z0-9_$]+$/
- Missing parameter
- PrerenderDynamicEndpointPathCollide
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/6eef103dbc8fea50.
Report an issue: GitHub.
Appendix: 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 52e6c34790)