remix-run/remix · error · ParseError
dangling escape
Error message
dangling escape
What it means
Pattern syntax supports backslash escapes for literal special characters. A backslash was found at the very end of the part span with nothing after it to escape, so it cannot form a valid escape sequence. parsePart throws 'dangling escape' at the backslash's index.
Source
Thrown at packages/route-pattern/src/lib/route-pattern/parse.ts:122
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' })
tokenIndices.push(i)
i += 1
continue
}
if (char === '\\') {
if (i + 1 === span[1]) {
throw new ParseError('dangling escape', source, i)
}
let text = source.slice(i + 1, i + 2)
appendText(text)
i += 2
continue
}
appendText(char)
i += 1
}
let unmatchedOptional = optionalStack.at(-1)
if (unmatchedOptional !== undefined) {
throw new ParseError('unmatched (', source, unmatchedOptional.sourceIndex)
}
if (emptyOptionals.length > 0) {
throw new ParseError('empty optional', source, emptyOptionals[0])
}
View on GitHub (pinned to 9696913134)
Solutions
- Remove the trailing backslash or escape it as '\\\\' if a literal backslash is intended
- Double-check JS string escaping — in a JS literal '\\\\' is one backslash in the pattern
- Use the error position to find the dangling escape
Example fix
// before
let pattern = parseRoutePattern('/files/docs\\')
// after
let pattern = parseRoutePattern('/files/docs') Defensive patterns
Strategy: validation
Validate before calling
if (source.endsWith('\\') && !source.endsWith('\\\\')) throw new Error('Dangling escape in pattern') Type guard
null
Try / catch
try { parseRoutePattern(source) } catch (e) { if (e instanceof ParseError && e.message === 'dangling escape') { /* fix or trim trailing backslash */ } } Prevention
- Remember JS strings double-escape backslashes
- Validate generated patterns before registration
When it happens
Trigger: Calling parseRoutePattern with a pattern ending in an unpaired '\', e.g. '/files/docs\\' or 'C\\' style Windows-ish fragments, or where string interpolation dropped the escaped character.
Common situations: JS string templating where '\\' was meant to be a literal backslash but ended up as the pattern's escape char with no following char; truncation during edits; escaping a separator incorrectly.
Related errors
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/a711a0db09da72e6.
Report an issue: GitHub.