denoland/deno · error

Unexpected end of string at {}.

Error message

Unexpected end of string at {}.

What it means

cli/lsp/path_to_regex.rs:86 is the lexer for the LSP's path-to-regex templates (registry schemas). On a backslash it consumes the next character as an EscapedChar token; if the input ends immediately after the '\', there is no character to read and it errors with "Unexpected end of string at {index}". The index reported is the position of the (missing) escaped character.

Source

Thrown at cli/lsp/path_to_regex.rs:86

  let mut chars = s.chars().peekable();
  let mut index = 0_usize;

  loop {
    match chars.next() {
      None => break,
      Some(c) if c == '*' || c == '+' || c == '?' => {
        tokens.push(LexToken {
          token_type: TokenType::Modifier,
          index,
          value: c.to_string(),
        });
        index += 1;
      }
      Some('\\') => {
        index += 1;
        let value = chars
          .next()
          .ok_or_else(|| anyhow!("Unexpected end of string at {}.", index))?;
        tokens.push(LexToken {
          token_type: TokenType::EscapedChar,
          index,
          value: value.to_string(),
        });
        index += 1;
      }
      Some('{') => {
        tokens.push(LexToken {
          token_type: TokenType::Open,
          index,
          value: '{'.to_string(),
        });
        index += 1;
      }
      Some('}') => {
        tokens.push(LexToken {
          token_type: TokenType::Close,

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Remove the trailing backslash from the schema string
  2. Double-escape when it is intentional: JSON needs "\\\\" to yield a literal backslash inside the pattern
  3. Run the schema through a path-to-regex checker before publishing the config

Example fix

// before
{ "schema": "/x/:pkg([a-z]+)\\" }

// after
{ "schema": "/x/:pkg([a-z]+)" }
Defensive patterns

Strategy: validation

Validate before calling

function endsWithDanglingEscape(s: string): boolean {
  // count trailing backslashes; odd count means a dangling escape
  let n = 0;
  for (let i = s.length - 1; i >= 0 && s[i] === "\\"; i--) n++;
  return n % 2 === 1;
}

Prevention

When it happens

Trigger: A registry schema string ending in a single backslash, e.g. "/x/:pkg([a-z]+)\\" or "/static\\"; also a URL-encoded %5C at the very end of a schema being lexed when the host is enabled for completions.

Common situations: Hand-escaping in JSON where one level of backslash was lost ("\\" collapsing to "\"); trailing Windows-style path separators pasted into a schema; sed/regex transformations that leave a stray escape.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/b741c3c61f0688a6. Report an issue: GitHub.