denoland/deno · error
Unbalanced pattern at {}.
Error message
Unbalanced pattern at {}. What it means
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 '('.
Source
Thrown at cli/lsp/path_to_regex.rs:182
break;
}
} else if next_char == Some(&'(') {
count += 1;
pattern.push(chars.next().unwrap());
if chars.peek() != Some(&'?') {
return Err(anyhow!(
"Capturing groups are not allowed at {}.",
index + pattern.len()
));
}
continue;
}
pattern.push(chars.next().unwrap());
}
if count > 0 {
return Err(anyhow!("Unbalanced pattern at {}.", index));
}
if pattern.is_empty() {
return Err(anyhow!("Missing pattern at {}.", index));
}
let pattern_len = pattern.len();
tokens.push(LexToken {
token_type: TokenType::Pattern,
index,
value: pattern,
});
index += 2 + pattern_len;
}
Some(c) => {
tokens.push(LexToken {
token_type: TokenType::Char,
index,
value: c.to_string(),
});View on GitHub (pinned to 89f33cbef2)
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
Example fix
// before
{ "schema": "/x/:pkg([a-z+" }
// after
{ "schema": "/x/:pkg([a-z]+)" } Defensive patterns
Strategy: validation
Validate before calling
function isBalanced(s: string): boolean {
let depth = 0;
for (let i = 0; i < s.length; i++) {
const c = s[i];
if (c === "\\") { i++; continue; }
if (c === "(") depth++;
else if (c === ")") depth--;
if (depth < 0) return false;
}
return depth === 0;
} Prevention
- 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
When it happens
Trigger: 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]+)".
Common situations: Hand-editing long character classes and losing the tail; JSON edits that truncate the schema; diff merges deleting a single ')'.
Related errors
- Pattern cannot start with "?" at {}.
- Capturing groups are not allowed at {}.
- Unexpected end of string at {}.
- Missing parameter name at {}
- Unexpected termination of string.
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/2dfa2e37952348e5.
Report an issue: GitHub.