{"record":{"id":"ffa1c75c97336163","repo":"remix-run/remix","slug":"invalid-pathname-variable","errorCode":null,"errorMessage":"invalid-pathname-variable","messagePattern":"invalid-pathname-variable","errorType":"validation","errorClass":"CreateHrefError","httpStatus":null,"severity":"error","filePath":"packages/route-pattern/src/lib/href.ts","lineNumber":338,"sourceCode":"      return `invalid hostname variable param: ${JSON.stringify(details.value)} contains ${JSON.stringify(details.char)}`\n    }\n\n    if (details.type === 'invalid-hostname-wildcard') {\n      return `invalid hostname wildcard param: ${JSON.stringify(details.value)} contains ${JSON.stringify(details.char)}`\n    }\n\n    if (details.type === 'invalid-pathname-variable') {\n      return `invalid pathname variable param: '${details.paramName}' cannot be empty\\n\\nPattern: ${details.pattern}\\nValue: ${JSON.stringify(details.value)}`\n    }\n\n    unreachable(details)\n  }\n}\n\nfunction encodePathnameVariableParam(pattern: RoutePattern, paramName: string, value: unknown) {\n  let serialized = String(value)\n  if (serialized.length === 0) {\n    throw new CreateHrefError({\n      type: 'invalid-pathname-variable',\n      pattern,\n      paramName,\n      value: serialized,\n    })\n  }\n  return encodePathnameVariableSegment(serialized)\n}\n\nexport function encodePathnameVariable(value: unknown) {\n  return encodePathnameVariableSegment(String(value))\n}\n\nexport function encodePathnameWildcard(value: unknown) {\n  return String(value).split('/').map(encodePathnameSegment).join('/')\n}\n\nfunction encodePathnameSegment(value: string): string {","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/route-pattern/src/lib/href.ts#L320-L356","documentation":"A pathname variable param was serialized to an empty string. Pathname segments cannot be empty (that would produce a double slash or collapse the path), so href creation fails with invalid-pathname-variable naming the offending param.","triggerScenarios":"Calling href with a param whose String(value) is '' for a `:param` used directly as a pathname segment, e.g. pattern `/users/:id` with params { id: '' } or { id: undefined } coerced to 'undefined'-like edge cases where an empty string is explicitly passed.","commonSituations":"Passing form or URL state that can be empty straight into link builders; trimming user input before validation; defaulting params to '' instead of omitting them; number 0 vs empty string confusion after formatting.","solutions":["Default or guard the param before calling href: skip the link or substitute a placeholder","Allow the segment to be optional in the pattern: `/users(/:id)`","Validate params with a schema (zod etc.) requiring non-empty strings for path params"],"exampleFix":"// before\nhref(userPattern, { id: user.id ?? '' })\n\n// after\nhref(userPattern, { id: user.id! })","handlingStrategy":"validation","validationCode":"for (let [k, v] of Object.entries(params)) {\n  if (typeof v === 'string' && v === '') throw new Error(`Param ${k} is empty`)\n}","typeGuard":"function isNonEmptyParam(value: unknown): value is string | number {\n  return String(value ?? '').length > 0\n}","tryCatchPattern":"try { href(pattern, params) } catch (e) { if (e?.type === 'invalid-pathname-variable') { /* default the param */ } }","preventionTips":["Never default path params to ''","Validate form-derived params with a schema"],"tags":["route-pattern","href","params","pathname"],"backgroundTag":"invalid-route-param-value","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}