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

  1. Remove the trailing backslash or escape it as '\\\\' if a literal backslash is intended
  2. Double-check JS string escaping — in a JS literal '\\\\' is one backslash in the pattern
  3. 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

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.