{"record":{"id":"2dfa2e37952348e5","repo":"denoland/deno","slug":"unbalanced-pattern-at","errorCode":null,"errorMessage":"Unbalanced pattern at {}.","messagePattern":"Unbalanced pattern at (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/lsp/path_to_regex.rs","lineNumber":182,"sourceCode":"              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            }\n            continue;\n          }\n\n          pattern.push(chars.next().unwrap());\n        }\n\n        if count > 0 {\n          return Err(anyhow!(\"Unbalanced pattern at {}.\", index));\n        }\n        if pattern.is_empty() {\n          return Err(anyhow!(\"Missing pattern at {}.\", index));\n        }\n        let pattern_len = pattern.len();\n        tokens.push(LexToken {\n          token_type: TokenType::Pattern,\n          index,\n          value: pattern,\n        });\n        index += 2 + pattern_len;\n      }\n      Some(c) => {\n        tokens.push(LexToken {\n          token_type: TokenType::Char,\n          index,\n          value: c.to_string(),\n        });","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/lsp/path_to_regex.rs#L164-L200","documentation":"Final balance check of the pattern lexer at cli/lsp/path_to_regex.rs:182: the '(' that opens a placeholder's custom regex decrements its counter on each matching ')'; if the scan reaches end-of-input with count > 0, the closing paren is missing and the lexer errors with \"Unbalanced pattern at {index}\" pointing at the opening '('.","triggerScenarios":"A schema with an unterminated inline pattern: \"/x/:pkg([a-z+\" (no closing parenthesis), or nested groups where one ')' was dropped: \"/x/:pkg((?:[a-z]+)\".","commonSituations":"Hand-editing long character classes and losing the tail; JSON edits that truncate the schema; diff merges deleting a single ')'.","solutions":["Close the pattern: \"/x/:pkg([a-z]+)\"","Count parens in both directions or lint the schema with a balanced-delimiter check before publishing","Prefer simple character classes over deeply nested groups to reduce the chance of imbalance"],"exampleFix":"// before\n{ \"schema\": \"/x/:pkg([a-z+\" }\n\n// after\n{ \"schema\": \"/x/:pkg([a-z]+)\" }","handlingStrategy":"validation","validationCode":"function isBalanced(s: string): boolean {\n  let depth = 0;\n  for (let i = 0; i < s.length; i++) {\n    const c = s[i];\n    if (c === \"\\\\\") { i++; continue; }\n    if (c === \"(\") depth++;\n    else if (c === \")\") depth--;\n    if (depth < 0) return false;\n  }\n  return depth === 0;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run a balanced-paren check over every schema before publishing the registry config","Avoid deep nesting; flatten alternations into character classes where possible","Editor trick: place the cursor on '(' and use bracket matching to confirm the closer exists"],"tags":["lsp","registry","schema","regex"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}