{"record":{"id":"f2f89323c2e83027","repo":"withastro/astro","slug":"prerenderdynamicendpointpathcollide","errorCode":"PrerenderDynamicEndpointPathCollide","errorMessage":"Could not render `${pathname}` with an `undefined` param as the generated path will collide during prerendering. Prevent passing `undefined` as `params` for the endpoint's `getStaticPaths()` function, or add an additional extension to the endpoint's filename.","messagePattern":"Could not render `(.+?)` with an `undefined` param as the generated path will collide during prerendering\\. Prevent passing `undefined` as `params` for the endpoint's `getStaticPaths\\(\\)` function, or add an additional extension to the endpoint's filename\\.","errorType":"validation","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/render/params-and-props.ts","lineNumber":145,"sourceCode":"\n/**\n * If we have an endpoint at `src/pages/api/[slug].ts` that's prerendered, and the `slug`\n * is `undefined`, throw an error as we can't generate the `/api` file and `/api` directory\n * at the same time. Using something like `[slug].json.ts` instead will work.\n */\nfunction validatePrerenderEndpointCollision(\n\troute: RouteData,\n\tmod: ComponentInstance,\n\tparams: Params,\n) {\n\tif (route.type === 'endpoint' && mod.getStaticPaths) {\n\t\tconst lastSegment = route.segments[route.segments.length - 1];\n\t\tconst paramValues = Object.values(params);\n\t\tconst lastParam = paramValues[paramValues.length - 1];\n\t\t// Check last segment is solely `[slug]` or `[...slug]` case (dynamic). Make sure it's not\n\t\t// `foo[slug].js` by checking segment length === 1. Also check here if that param is undefined.\n\t\tif (lastSegment.length === 1 && lastSegment[0].dynamic && lastParam === undefined) {\n\t\t\tthrow new AstroError({\n\t\t\t\t...AstroErrorData.PrerenderDynamicEndpointPathCollide,\n\t\t\t\tmessage: AstroErrorData.PrerenderDynamicEndpointPathCollide.message(route.route),\n\t\t\t\thint: AstroErrorData.PrerenderDynamicEndpointPathCollide.hint(route.component),\n\t\t\t\tlocation: {\n\t\t\t\t\tfile: route.component,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n}\n","sourceCodeStart":127,"sourceCodeEnd":156,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/core/render/params-and-props.ts#L127-L156","documentation":"A prerendered endpoint whose last path segment is purely dynamic (e.g. [slug].ts) received an undefined param value. An undefined last param produces an empty trailing segment, colliding with the parent directory's index output. Astro aborts to avoid overwriting another generated file.","triggerScenarios":"Endpoint file pages/api/[slug].ts with getStaticPaths returning { params: { slug: undefined } }; a rest param endpoint with an empty value; data source yielding undefined for the last param.","commonSituations":"Migrating a page-style route to an endpoint; conditionally returning undefined params; wanting an 'index' style output from a dynamic endpoint.","solutions":["Stop passing undefined for the last-segment param — always provide a concrete string.","Add an extension to the filename so the output path differs, e.g. rename [slug].ts to [slug].json.ts.","Split the route: a dedicated index file for the empty case plus the dynamic file for named values."],"exampleFix":"// before — file: src/pages/api/[slug].ts\nexport async function getStaticPaths() {\n  return [{ params: { slug: undefined } }]; // collides\n}\n\n// after — rename file to src/pages/api/[slug].json.ts\nexport async function getStaticPaths() {\n  return [{ params: { slug: 'item' } }];\n}","handlingStrategy":"validation","validationCode":"function lastParamDefined(params: Record<string, unknown>, key: string): boolean {\n  return params[key] !== undefined;\n}\n// in getStaticPaths, filter or fix entries where the last-segment param is undefined","typeGuard":"function hasDefinedLastParam(params: Record<string, unknown>, lastKey: string): params is Record<string, string> {\n  return typeof params[lastKey] === 'string';\n}","tryCatchPattern":null,"preventionTips":["Never pass undefined for the last dynamic segment of an endpoint; coerce to a real string.","Give endpoint files an explicit extension (e.g. [slug].json.ts) to decouple the output path.","Unit-test getStaticPaths output to assert all last params are strings."],"tags":["endpoint","prerender","routing","path-collision"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}