remix-run/remix · error · ParseError
missing variable name
Error message
missing variable name
What it means
Pattern syntax uses `:name` for variable capture. A ':' was encountered but no valid identifier follows it before the end of the span, so there is no name to bind the capture to. parsePart throws 'missing variable name' pointing at the colon.
Source
Thrown at packages/route-pattern/src/lib/route-pattern/parse.ts:96
let optional = optionalStack.pop()
if (optional === undefined) {
throw new ParseError('unmatched )', source, i)
}
if (optional.tokenIndex === tokens.length - 1) {
emptyOptionals.push(optional.sourceIndex)
}
optionals.set(optional.tokenIndex, tokens.length)
tokens.push({ type: char })
tokenIndices.push(i)
i += 1
continue
}
if (char === ':') {
i += 1
let name = IDENTIFIER_RE.exec(source.slice(i, span[1]))?.[0]
if (!name) {
throw new ParseError('missing variable name', source, i - 1)
}
tokens.push({ type: ':', name })
tokenIndices.push(i - 1)
i += name.length
continue
}
if (char === '*') {
i += 1
let name = IDENTIFIER_RE.exec(source.slice(i, span[1]))?.[0]
tokens.push({ type: '*', name: name ?? '*' })
tokenIndices.push(i - 1)
i += name?.length ?? 0
continue
}
if (char === separator) {
tokens.push({ type: 'separator' })View on GitHub (pinned to 9696913134)
Solutions
- Give the variable a name: '/users/:id'
- Escape colons that are literal: '/schedule/\:time' (see the escape handling in the same parser)
- Check the error position — it points at the offending ':'
Example fix
// before
let pattern = parseRoutePattern('/users/:')
// after
let pattern = parseRoutePattern('/users/:id') Defensive patterns
Strategy: validation
Validate before calling
let colonNames = [...source.matchAll(/:(\w*)/g)].filter(m => !m[1])
if (colonNames.length) throw new Error('Colon without a variable name') Type guard
null
Try / catch
try { parseRoutePattern(source) } catch (e) { if (e instanceof ParseError && e.message === 'missing variable name') { /* fix at e.position */ } } Prevention
- Escape literal colons with \\
- Test every pattern constant parses
When it happens
Trigger: Calling parseRoutePattern with a pattern like '/users/:' , '/:' , or '/files/:.json' where ':' is followed by a non-identifier character or nothing. Only IDENTIFIER_RE-compatible names are accepted.
Common situations: Truncating a pattern during refactor (':id' reduced to ':'); a colon intended literally in a path (e.g. time '12:30') left unescaped; templating bug leaving an empty placeholder '{{user}}' removed but ':' kept.
Related errors
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/56f516dffb3438c2.
Report an issue: GitHub.