withastro/astro · error · AstroError

GetStaticPathsExpectedParams

GetStaticPathsExpectedParams

Error message

Missing or empty required `params` property on `getStaticPaths()` route.

What it means

Each getStaticPaths() entry must carry a non-empty params object — it is what Astro feeds into route pattern generation. validateGetStaticPathsResult throws GetStaticPathsExpectedParams when an entry's params is undefined, null, or an object with zero keys. An entry without params cannot produce any URL, and an empty params object on a dynamic route would emit a broken path.

Solutions

  1. Add a params object with a value for every dynamic segment in the filename: { params: { slug }, props: { post } }.
  2. Check for typos: the key must be exactly params (plural), and its keys must match the [param] names in the route file.
  3. Filter out items whose param value is missing before returning: items.filter(i => i.slug).map(...).

Example fix

// before
export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map((post) => ({ props: { post } })); // no params
}

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

Strategy: type-guard

Validate before calling

const entries = items.map((i) => ({ params: { slug: i.slug }, props: { i } }));
const valid = entries.every((e) => e.params && Object.keys(e.params).length > 0);
if (!valid) throw new Error('every getStaticPaths entry needs non-empty params');
return entries;

Type guard

function hasParams(
  e: unknown,
): e is { params: Record<string, string | undefined> } {
  return (
    typeof e === 'object' &&
    e !== null &&
    'params' in e &&
    typeof (e as { params: unknown }).params === 'object' &&
    (e as { params: object }).params !== null &&
    Object.keys((e as { params: object }).params).length > 0
  );
}

Prevention

When it happens

Trigger: Returning [{ props: { post } }] and forgetting params; destructuring params from the wrong variable so it is undefined ({ params: post.params } where post.params does not exist); returning entries like { params: {} }; a typo such as { param: { slug } } (singular).

Common situations: Entries built from props-only data; content collections where the developer passes props but assumes Astro infers params; copy-paste of an entry template with params deleted; keys computed dynamically that end up empty for some items.

Related errors


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

Appendix: source

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

		});
	}

	result.forEach((pathObject) => {
		if ((typeof pathObject === 'object' && Array.isArray(pathObject)) || pathObject === null) {
			throw new AstroError({
				...AstroErrorData.InvalidGetStaticPathsEntry,
				message: AstroErrorData.InvalidGetStaticPathsEntry.message(
					Array.isArray(pathObject) ? 'array' : typeof pathObject,
				),
			});
		}

		if (
			pathObject.params === undefined ||
			pathObject.params === null ||
			(pathObject.params && Object.keys(pathObject.params).length === 0)
		) {
			throw new AstroError({
				...AstroErrorData.GetStaticPathsExpectedParams,
				location: {
					file: route.component,
				},
			});
		}
	});
}

View on GitHub (pinned to 52e6c34790)