{"record":{"id":"a5d0fd21213ef705","repo":"withastro/astro","slug":"missing-parameter-part-content","errorCode":null,"errorMessage":"Missing parameter: ${part.content}","messagePattern":"Missing parameter: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/routing/generator.ts","lineNumber":28,"sourceCode":"function sanitizeParams(params: Record<string, string | number>): Record<string, string | number> {\n\treturn Object.fromEntries(\n\t\tObject.entries(params).map(([key, value]) => {\n\t\t\tif (typeof value === 'string') {\n\t\t\t\treturn [key, value.normalize().replace(/#/g, '%23').replace(/\\?/g, '%3F')];\n\t\t\t}\n\t\t\treturn [key, value];\n\t\t}),\n\t);\n}\n\nfunction getParameter(part: RoutePart, params: Record<string, string | number>): string | number {\n\tif (part.spread) {\n\t\treturn params[part.content.slice(3)] ?? '';\n\t}\n\n\tif (part.dynamic) {\n\t\tif (params[part.content] === undefined) {\n\t\t\tthrow new TypeError(`Missing parameter: ${part.content}`);\n\t\t}\n\n\t\treturn params[part.content];\n\t}\n\n\treturn part.content\n\t\t.normalize()\n\t\t.replace(/\\?/g, '%3F')\n\t\t.replace(/#/g, '%23')\n\t\t.replace(/%5B/g, '[')\n\t\t.replace(/%5D/g, ']');\n}\n\nfunction getSegment(segment: RoutePart[], params: Record<string, string | number>): string {\n\tconst segmentPath = segment.map((part) => getParameter(part, params)).join('');\n\n\treturn segmentPath ? collapseDuplicateLeadingSlashes('/' + segmentPath) : '';\n}","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/core/routing/generator.ts#L10-L46","documentation":"getParameter() in generator.ts threw a TypeError because a required dynamic route parameter was missing from the params object. For non-spread dynamic segments, params[name] must be defined; rest segments fall back to '' but plain dynamic segments do not, so an undefined value is a hard error during URL generation.","triggerScenarios":"Calling the route generator with an incomplete params object (e.g. generateRoute({ id: '1' }) for /[id]/[section]); a getStaticPaths entry omitting a param; programmatic route generation missing a key.","commonSituations":"Returning getStaticPaths entries that omit one param; refactoring a route to add a segment without updating all param producers; downstream code calling the generator directly.","solutions":["Provide every dynamic (non-rest) param as a defined string in the params object.","In getStaticPaths(), make sure each entry's params includes all bracketed segment names.","If a param should be optional, use a rest segment [...name] which tolerates absence."],"exampleFix":"// before — route /[id]/[section]\nexport async function getStaticPaths() {\n  return [{ params: { id: '1' } }]; // section missing\n}\n\n// after\nexport async function getStaticPaths() {\n  return [{ params: { id: '1', section: 'intro' } }];\n}","handlingStrategy":"validation","validationCode":"function hasAllDynamicParams(params: Record<string, string>, segmentNames: string[]): boolean {\n  return segmentNames.every(name => params[name] !== undefined);\n}\n// before generating a route, assert all dynamic segment names are present","typeGuard":"function hasRequiredParams(params: Record<string, unknown>, required: string[]): params is Record<string, string> {\n  return required.every(k => typeof params[k] === 'string');\n}","tryCatchPattern":"try {\n  generateRoute(route, params);\n} catch (e) {\n  if (e instanceof TypeError && /Missing parameter/.test(e.message)) {\n    // backfill or skip this entry\n  }\n  throw e;\n}","preventionTips":["In getStaticPaths(), include every bracketed segment in params.","Use rest segments for genuinely optional params.","Type params as Record<string, string> to catch omissions at compile time."],"tags":["routing","dynamic-routes","getstaticpaths","generator"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}