{"record":{"id":"0ae89bac5102bc4e","repo":"denoland/deno","slug":"unexpected-termination-of-string","errorCode":null,"errorMessage":"Unexpected termination of string.","messagePattern":"Unexpected termination of string\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/lsp/path_to_regex.rs","lineNumber":156,"sourceCode":"\n        if chars.peek() == Some(&'?') {\n          return Err(anyhow!(\n            \"Pattern cannot start with \\\"?\\\" at {}.\",\n            index + 1\n          ));\n        }\n\n        loop {\n          let next_char = chars.peek();\n          if next_char.is_none() {\n            break;\n          }\n          if next_char == Some(&'\\\\') {\n            pattern.push(chars.next().unwrap());\n            pattern.push(\n              chars\n                .next()\n                .ok_or_else(|| anyhow!(\"Unexpected termination of string.\"))?,\n            );\n            continue;\n          }\n          if next_char == Some(&')') {\n            count -= 1;\n            if count == 0 {\n              chars.next();\n              break;\n            }\n          } else if next_char == Some(&'(') {\n            count += 1;\n            pattern.push(chars.next().unwrap());\n            if chars.peek() != Some(&'?') {\n              return Err(anyhow!(\n                \"Capturing groups are not allowed at {}.\",\n                index + pattern.len()\n              ));\n            }","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/lsp/path_to_regex.rs#L138-L174","documentation":"While scanning a parenthesized pattern, cli/lsp/path_to_regex.rs:156 pushes a backslash then requires one more character for the escape pair. If the input ends right after that backslash, chars.next() returns None and the lexer reports \"Unexpected termination of string.\" — the regex pattern was cut off mid-escape.","triggerScenarios":"A schema like \"/x/:pkg([a-z+\\\\\" where the pattern's closing ')' is missing and the string ends on a lone backslash; truncated config.json payloads.","commonSituations":"Under-escaped JSON (a planned \"\\\\\\\\\" becoming \"\\\\\"), string truncation from template length limits, or hand-merging schema edits that deleted the tail of the pattern.","solutions":["Close the pattern properly and escape backslashes in pairs: \"/x/:pkg([a-z\\\\.]+)\"","In JSON source, write \"\\\\\\\\\" for each literal backslash you want in the regex","Validate the schema with a path-to-regex parser before shipping"],"exampleFix":"// before\n{ \"schema\": \"/x/:pkg([a-z+\\\\\" }\n\n// after\n{ \"schema\": \"/x/:pkg([a-z.]+)\" }","handlingStrategy":"validation","validationCode":"function endsWithDanglingEscapeInsidePattern(s: string): boolean {\n  const open = s.lastIndexOf(\"(\");\n  if (open === -1) return false;\n  const tail = s.slice(open);\n  return !tail.includes(\")\") && endsWithDanglingEscape(tail);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Write escape pairs atomically: \\\\. not a lone \\","Close every parenthesis before ending the string; then check for dangling escapes","Keep patterns short so truncation is obvious in review"],"tags":["lsp","registry","schema","lexer"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}