3b1b/manim · error · ValueError

At least 2 mobjects needed for Exclusion.

Error message

At least 2 mobjects needed for Exclusion.

What it means

ValueError raised in Exclusion.__init__ (manimlib/mobject/boolean_ops.py:104). Exclusion computes pairwise XOR via pathops.xor starting with vmobjects[0] and vmobjects[1], so at least two operands are required; the guard fires before any geometry work.

Source

Thrown at manimlib/mobject/boolean_ops.py:104

            [_convert_vmobject_to_skia_path(vmobjects[1])],
            outpen.getPen(),
        )
        new_outpen = outpen
        for _i in range(2, len(vmobjects)):
            new_outpen = pathops.Path()
            pathops.intersection(
                [outpen],
                [_convert_vmobject_to_skia_path(vmobjects[_i])],
                new_outpen.getPen(),
            )
            outpen = new_outpen
        _convert_skia_path_to_vmobject(outpen, self)


class Exclusion(VMobject):
    def __init__(self, *vmobjects: VMobject, **kwargs):
        if len(vmobjects) < 2:
            raise ValueError("At least 2 mobjects needed for Exclusion.")
        super().__init__(**kwargs)
        outpen = pathops.Path()
        pathops.xor(
            [_convert_vmobject_to_skia_path(vmobjects[0])],
            [_convert_vmobject_to_skia_path(vmobjects[1])],
            outpen.getPen(),
        )
        new_outpen = outpen
        for _i in range(2, len(vmobjects)):
            new_outpen = pathops.Path()
            pathops.xor(
                [outpen],
                [_convert_vmobject_to_skia_path(vmobjects[_i])],
                new_outpen.getPen(),
            )
            outpen = new_outpen
        _convert_skia_path_to_vmobject(outpen, self)

View on GitHub (pinned to dee01804d4)

Solutions

  1. Pass at least two VMobjects: Exclusion(mob_a, mob_b)
  2. Validate collection length before splatting
  3. Use mob.copy() semantics if only one shape was intended

Example fix

# before
xor_shape = Exclusion(*mobs)  # raises when len(mobs) < 2

# after
if len(mobs) >= 2:
    xor_shape = Exclusion(*mobs)
else:
    raise SystemExit(f"Need >=2 mobjects, got {len(mobs)}")
Defensive patterns

Strategy: validation

Validate before calling

if len(mobs) >= 2:
    xor_shape = Exclusion(*mobs)
else:
    raise ValueError(f"Exclusion needs >= 2 mobjects, got {len(mobs)}")

Type guard

def is_exclusion_ready(mobs: list) -> bool:
    return len(mobs) >= 2

Prevention

When it happens

Trigger: Exclusion(one_mob), Exclusion(), or Exclusion(*mobs) where mobs contains fewer than two mobjects after programmatic filtering.

Common situations: Dynamic operand lists; user-config-driven scene building where an operand list degenerates to one element; refactors that removed an operand.

Related errors


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