3b1b/manim · error · ValueError

Missing '{' inserted

Error message

Missing '{' inserted

What it means

Raised by MathTex/Tex string processing (tex_mobject.py:108, break_up_by_substrings brace matching) when the LaTeX string contains more closing braces than unmatched opening braces — i.e. a '}' appears with nothing on the open-brace stack to pair with. The tokenizer pairs brace groups so substrings like \frac{...}{...} can be isolated, and unbalanced input is rejected.

Source

Thrown at manimlib/mobject/svg/tex_mobject.py:108

    @staticmethod
    def get_command_matches(string: str) -> list[re.Match]:
        # Lump together adjacent brace pairs
        pattern = re.compile(r"""
            (?P<command>\\(?:[a-zA-Z]+|.))
            |(?P<open>{+)
            |(?P<close>}+)
        """, flags=re.X | re.S)
        result = []
        open_stack = []
        for match_obj in pattern.finditer(string):
            if match_obj.group("open"):
                open_stack.append((match_obj.span(), len(result)))
            elif match_obj.group("close"):
                close_start, close_end = match_obj.span()
                while True:
                    if not open_stack:
                        raise ValueError("Missing '{' inserted")
                    (open_start, open_end), index = open_stack.pop()
                    n = min(open_end - open_start, close_end - close_start)
                    result.insert(index, pattern.fullmatch(
                        string, pos=open_end - n, endpos=open_end
                    ))
                    result.append(pattern.fullmatch(
                        string, pos=close_start, endpos=close_start + n
                    ))
                    close_start += n
                    if close_start < close_end:
                        continue
                    open_end -= n
                    if open_start < open_end:
                        open_stack.append(((open_start, open_end), index))
                    break
            else:
                result.append(match_obj)
        if open_stack:

View on GitHub (pinned to dee01804d4)

Solutions

  1. Balance the braces in the tex string; escape literal braces as \\{ and \\} in math mode when they should not group
  2. When using f-strings/format, remember braces for LaTeX must be doubled ({{ }}) or the string built by concatenation instead
  3. Add a quick sanity check that string.count('{') == string.count('}') after template rendering (ignoring escaped ones)

Example fix

# before
MathTex(r'\frac{a}{b}}')  # extra '}' -> raises

# after
MathTex(r'\frac{a}{b}')
Defensive patterns

Strategy: validation

Validate before calling

def braces_balanced(s: str) -> bool:
    depth = 0
    for ch in s:
        if ch == '{': depth += 1
        elif ch == '}': depth -= 1
        if depth < 0: return False
    return depth == 0

assert braces_balanced(tex_str)

Try / catch

from manimlib.mobject.svg.tex_mobject import Tex
try:
    tex = Tex(rendered_str)
except ValueError as e:
    if "Missing '{'" in str(e):
        tex = Tex(rendered_str.replace('}', r'\}'))

Prevention

When it happens

Trigger: MathTex(r'{a}') is fine; MathTex(r'}') or MathTex(r'\frac{a}}') raises 'Missing {'. Also occurs when isolating substrings with braces whose escaping (\\{) is lost through f-strings or .format so a literal } slips in unbalanced.

Common situations: Building Tex strings dynamically from templates where a variable can inject a bare '}'; using double-brace escaping incorrectly in f-strings; upgrading from older manim versions that silently tolerated unbalanced braces.

Related errors


AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14). Data as JSON: /api/errors/a5a4855a85c87ef1. Report an issue: GitHub.