withastro/astro · error · AstroError

GetStaticPathsRequired

GetStaticPathsRequired

Error message

`getStaticPaths()` function is required for dynamic routes. Make sure that you `export` a `getStaticPaths()` function from your dynamic route.

What it means

In Astro, a dynamic route (one with [param] segments) that is prerendered must declare which paths exist at build time via an exported getStaticPaths(). validateDynamicRouteModule throws GetStaticPathsRequired when the route will be prerendered (static output, or an SSR build where the route has prerender = true), it is not an internal route, and the module exports no getStaticPaths. Without it the build would not know which pages to emit.

Solutions

  1. Export getStaticPaths from the route: export async function getStaticPaths() { return (await getCollection('posts')).map(p => ({ params: { slug: p.slug } })); }
  2. If the route must render on demand, keep the project SSR and set export const prerender = false in that route (requires an adapter).
  3. If the route does not need to be dynamic, replace the [param] segment with a static filename.

Example fix

// before
// src/pages/blog/[slug].astro
---
const { slug } = Astro.params;
---

// after
// src/pages/blog/[slug].astro
---
export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map((post) => ({ params: { slug: post.slug }, props: { post } }));
}
const { post } = Astro.props;
---
Defensive patterns

Strategy: validation

Validate before calling

// fails fast at module load with your own message, instead of during build
import type { GetStaticPaths } from 'astro';

export const getStaticPaths: GetStaticPaths = async () => {
  /* ... */
};

Type guard

import type { RouteParams } from 'astro';

export function hasGetStaticPaths(mod: Record<string, unknown>): mod is { getStaticPaths: () => unknown } {
  return typeof mod.getStaticPaths === 'function';
}

Prevention

When it happens

Trigger: Creating src/pages/[slug].astro with no export function getStaticPaths() while output is 'static' (the default); setting export const prerender = true on a dynamic route in an output:'server' project; forgetting the export keyword (function getStaticPaths(){} stays module-local); renaming the export (getStaticpath, getStaticPathsS).

Common situations: New projects adding a blog [slug] page from a tutorial but skipping getStaticPaths; switching output from 'server' to 'static' where dynamic routes relied on the server; flipping a route to prerender = true without porting its data loading; upgrading Astro 4 -> 5 and hitting stricter checks.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/2d84d7e5d258ce83. Report an issue: GitHub.

Appendix: source

Thrown at packages/astro/src/core/routing/validation.ts:18

import type { ComponentInstance } from '../../types/astro.js';
import type { GetStaticPathsResult } from '../../types/public/common.js';
import type { RouteData } from '../../types/public/internal.js';
import { AstroError, AstroErrorData } from '../errors/index.js';

/** Error for deprecated or malformed route components */
export function validateDynamicRouteModule(
	mod: ComponentInstance,
	{
		ssr,
		route,
	}: {
		ssr: boolean;
		route: RouteData;
	},
) {
	if ((!ssr || route.prerender) && route.origin !== 'internal' && !mod.getStaticPaths) {
		throw new AstroError({
			...AstroErrorData.GetStaticPathsRequired,
			location: { file: route.component },
		});
	}
}

/** Throw error and log warnings for malformed getStaticPaths() response */
export function validateGetStaticPathsResult(result: GetStaticPathsResult, route: RouteData) {
	if (!Array.isArray(result)) {
		throw new AstroError({
			...AstroErrorData.InvalidGetStaticPathsReturn,
			message: AstroErrorData.InvalidGetStaticPathsReturn.message(typeof result),
			location: {
				file: route.component,
			},
		});
	}

View on GitHub (pinned to 52e6c34790)