remix-run/remix · error · CreateHrefError
invalid-pathname-variable
Error message
invalid-pathname-variable
What it means
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.
Source
Thrown at packages/route-pattern/src/lib/href.ts:338
return `invalid hostname variable param: ${JSON.stringify(details.value)} contains ${JSON.stringify(details.char)}`
}
if (details.type === 'invalid-hostname-wildcard') {
return `invalid hostname wildcard param: ${JSON.stringify(details.value)} contains ${JSON.stringify(details.char)}`
}
if (details.type === 'invalid-pathname-variable') {
return `invalid pathname variable param: '${details.paramName}' cannot be empty\n\nPattern: ${details.pattern}\nValue: ${JSON.stringify(details.value)}`
}
unreachable(details)
}
}
function encodePathnameVariableParam(pattern: RoutePattern, paramName: string, value: unknown) {
let serialized = String(value)
if (serialized.length === 0) {
throw new CreateHrefError({
type: 'invalid-pathname-variable',
pattern,
paramName,
value: serialized,
})
}
return encodePathnameVariableSegment(serialized)
}
export function encodePathnameVariable(value: unknown) {
return encodePathnameVariableSegment(String(value))
}
export function encodePathnameWildcard(value: unknown) {
return String(value).split('/').map(encodePathnameSegment).join('/')
}
function encodePathnameSegment(value: string): string {View on GitHub (pinned to 9696913134)
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
Example fix
// before
href(userPattern, { id: user.id ?? '' })
// after
href(userPattern, { id: user.id! }) Defensive patterns
Strategy: validation
Validate before calling
for (let [k, v] of Object.entries(params)) {
if (typeof v === 'string' && v === '') throw new Error(`Param ${k} is empty`)
} Type guard
function isNonEmptyParam(value: unknown): value is string | number {
return String(value ?? '').length > 0
} Try / catch
try { href(pattern, params) } catch (e) { if (e?.type === 'invalid-pathname-variable') { /* default the param */ } } Prevention
- Never default path params to ''
- Validate form-derived params with a schema
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/ffa1c75c97336163.
Report an issue: GitHub.