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
					? undefined

View on GitHub (pinned to d081033d5f)

Solutions

  1. Rename the route file so it contains [page], e.g. src/pages/blog/[page].astro.
  2. For catch-all pagination use [...page].astro.
  3. 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

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


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/6eef103dbc8fea50. Report an issue: GitHub.