sveltejs/kit · error · Error

Each member of ${keypath} must be either '*' or an absolute

Error message

Each member of ${keypath} must be either '*' or an absolute path beginning with '/' — saw '${page}'

What it means

Each entry in `kit.prerender.entries` must be either the wildcard '*' or an absolute route path starting with '/'. The validator iterates the array and throws as soon as it finds a member that is neither. This keeps the prerender entry list unambiguous about what URLs to crawl.

Source

Thrown at packages/kit/src/core/config/options.js:261

			return origin;
		}),
		relative: boolean(true)
	}),

	preprocess: any(),

	prerender: object({
		concurrency: number(1),
		crawl: boolean(true),
		entries: validate(['*'], (input, keypath) => {
			if (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {
				throw new Error(`${keypath} must be an array of strings`);
			}

			input.forEach((page) => {
				if (page !== '*' && page[0] !== '/') {
					throw new Error(
						`Each member of ${keypath} must be either '*' or an absolute path beginning with '/' — saw '${page}'`
					);
				}
			});

			return input;
		}),

		handleHttpError: prerender_handler,
		handleMissingId: prerender_handler,
		handleEntryGeneratorMismatch: prerender_handler,
		handleUnseenRoutes: prerender_handler,
		handleInvalidUrl: prerender_handler,

		origin: removed(
			(keypath) => `\`${keypath}\` has been removed in favour of \`config.paths.origin\``
		)
	}),

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Prefix each path with '/' so it is an absolute path, e.g. '/about'.
  2. Use '*' as the single entry if you want to crawl all discoverable pages.
  3. Normalize dynamically generated entries with a check like page.startsWith('/') || page === '*'.

Example fix

// before
kit: { prerender: { entries: ['about', 'blog/first-post'] } }
// after
kit: { prerender: { entries: ['/about', '/blog/first-post'] } }
Defensive patterns

Strategy: validation

Validate before calling

const entries = cfg.kit?.prerender?.entries ?? [];
const bad = entries.filter((p) => p !== '*' && !p.startsWith('/'));
if (bad.length) throw new Error(`entries must start with '/': ${bad.join(', ')}`);

Type guard

function isValidPrerenderEntry(p) { return p === '*' || (typeof p === 'string' && p.startsWith('/')); }

Try / catch

try {
  build(config);
} catch (e) {
  if (String(e.message).includes("absolute path beginning with '/'")) {
    config.kit.prerender.entries = config.kit.prerender.entries.map((p) => (p === '*' ? p : '/' + p.replace(/^\/+/, '')));
  } else throw e;
}

Prevention

When it happens

Trigger: entries containing relative paths ('about'), full URLs ('https://example.com/about'), or paths missing the leading slash ('/about'.replace('/','')), e.g. entries: ['about', 'contact'].

Common situations: Typing route IDs without the leading slash, pasting full URLs from a browser, or generating entries from a routes manifest that stores names without slashes.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/2e3d01ec9ec057bf. Report an issue: GitHub.