{"record":{"id":"91fe33caa33f5f6f","repo":"fishaudio/fish-speech","slug":"unbalanced-braces","errorCode":null,"errorMessage":"Unbalanced braces","messagePattern":"Unbalanced braces","errorType":"validation","errorClass":"UnbalancedBracesError","httpStatus":null,"severity":"error","filePath":"fish_speech/utils/braceexpand.py","lineNumber":178,"sourceCode":"    bracketdepth = 0\n    items: list[Iterable[str]] = []\n\n    # print 'sequence:', seq\n    while pos < len(seq):\n        if escape and seq[pos] == \"\\\\\":\n            pos += 2\n            continue\n        elif seq[pos] == \"{\":\n            bracketdepth += 1\n        elif seq[pos] == \"}\":\n            bracketdepth -= 1\n        elif seq[pos] == \",\" and bracketdepth == 0:\n            items.append(parse_pattern(seq[start:pos], escape))\n            start = pos + 1  # skip the comma\n        pos += 1\n\n    if bracketdepth != 0:\n        raise UnbalancedBracesError\n    if not items:\n        return None\n\n    # part after the last comma (may be the empty string)\n    items.append(parse_pattern(seq[start:], escape))\n    return chain(*items)\n\n\ndef make_int_range(left: str, right: str, incr: Optional[str] = None) -> Iterator[str]:\n    if any([s.startswith((\"0\", \"-0\")) for s in (left, right) if s not in (\"0\", \"-0\")]):\n        padding = max(len(left), len(right))\n    else:\n        padding = 0\n    step = (int(incr) or 1) if incr else 1\n    start = int(left)\n    end = int(right)\n    r = range(start, end + 1, step) if start < end else range(start, end - 1, -step)\n    fmt = \"%0{}d\".format(padding)","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/fishaudio/fish-speech/blob/befe4001745417f8c42131739d862b8a6fdbd15a/fish_speech/utils/braceexpand.py#L160-L196","documentation":"While splitting a brace expression on top-level commas, parse_sequence detects an unterminated bracket and raises UnbalancedBracesError (the bare constructor yields the default 'Unbalanced braces' message).","triggerScenarios":"Expanding a nested/sequence pattern where a '{' inside the sequence is never closed, e.g. '{a{1,2,b}' or '{x,'.","commonSituations":"Nested brace patterns built programmatically; truncated user input; patterns passed through a layer that strips characters.","solutions":["Rewrite the pattern with matched braces at every nesting level","Test nested patterns with small examples before production use","Catch UnbalancedBracesError around user-facing pattern expansion"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"def braces_balanced(s, i=0, depth=0):\n    while i < len(s):\n        if s[i] == \"\\\\\": i += 2; continue\n        if s[i] == \"{\": depth += 1\n        elif s[i] == \"}\": depth -= 1\n        i += 1\n    return depth == 0","typeGuard":null,"tryCatchPattern":"from fish_speech.utils.braceexpand import UnbalancedBracesError\ntry:\n    expanded = list(braceexpand(pattern))\nexcept UnbalancedBracesError:\n    expanded = [pattern]  # fall back to literal","preventionTips":["Use a brace-balance validator on user input","Escape literal braces"],"tags":["parsing","brace-expansion","user-input"],"backgroundTag":"unbalanced-braces","analyzedSha":"befe4001745417f8c42131739d862b8a6fdbd15a","analyzedAt":"2026-08-27T21:31:45.703Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}