{"record":{"id":"2e3d01ec9ec057bf","repo":"sveltejs/kit","slug":"each-member-of-keypath-must-be-either-or-an","errorCode":null,"errorMessage":"Each member of ${keypath} must be either '*' or an absolute path beginning with '/' — saw '${page}'","messagePattern":"Each member of (.+?) must be either '\\*' or an absolute path beginning with '/' — saw '(.+?)'","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/core/config/options.js","lineNumber":261,"sourceCode":"\n\t\t\treturn origin;\n\t\t}),\n\t\trelative: boolean(true)\n\t}),\n\n\tpreprocess: any(),\n\n\tprerender: object({\n\t\tconcurrency: number(1),\n\t\tcrawl: boolean(true),\n\t\tentries: validate(['*'], (input, keypath) => {\n\t\t\tif (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {\n\t\t\t\tthrow new Error(`${keypath} must be an array of strings`);\n\t\t\t}\n\n\t\t\tinput.forEach((page) => {\n\t\t\t\tif (page !== '*' && page[0] !== '/') {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Each member of ${keypath} must be either '*' or an absolute path beginning with '/' — saw '${page}'`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn input;\n\t\t}),\n\n\t\thandleHttpError: prerender_handler,\n\t\thandleMissingId: prerender_handler,\n\t\thandleEntryGeneratorMismatch: prerender_handler,\n\t\thandleUnseenRoutes: prerender_handler,\n\t\thandleInvalidUrl: prerender_handler,\n\n\t\torigin: removed(\n\t\t\t(keypath) => `\\`${keypath}\\` has been removed in favour of \\`config.paths.origin\\``\n\t\t)\n\t}),","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/core/config/options.js#L243-L279","documentation":"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.","triggerScenarios":"entries containing relative paths ('about'), full URLs ('https://example.com/about'), or paths missing the leading slash ('/about'.replace('/','')), e.g. entries: ['about', 'contact'].","commonSituations":"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.","solutions":["Prefix each path with '/' so it is an absolute path, e.g. '/about'.","Use '*' as the single entry if you want to crawl all discoverable pages.","Normalize dynamically generated entries with a check like page.startsWith('/') || page === '*'."],"exampleFix":"// before\nkit: { prerender: { entries: ['about', 'blog/first-post'] } }\n// after\nkit: { prerender: { entries: ['/about', '/blog/first-post'] } }","handlingStrategy":"validation","validationCode":"const entries = cfg.kit?.prerender?.entries ?? [];\nconst bad = entries.filter((p) => p !== '*' && !p.startsWith('/'));\nif (bad.length) throw new Error(`entries must start with '/': ${bad.join(', ')}`);","typeGuard":"function isValidPrerenderEntry(p) { return p === '*' || (typeof p === 'string' && p.startsWith('/')); }","tryCatchPattern":"try {\n  build(config);\n} catch (e) {\n  if (String(e.message).includes(\"absolute path beginning with '/'\")) {\n    config.kit.prerender.entries = config.kit.prerender.entries.map((p) => (p === '*' ? p : '/' + p.replace(/^\\/+/, '')));\n  } else throw e;\n}","preventionTips":["Normalize route paths with a leading slash when generating entries programmatically.","Never put full URLs in entries — use '*' or absolute paths only.","Unit-test any script that produces the entries list."],"tags":["sveltekit","config-validation","prerender"],"backgroundTag":"schema-validation-failed","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}