3b1b/manim · error · Exception

Mobject cannot contain self

Error message

Mobject cannot contain self

What it means

Exception('Mobject cannot contain self') raised by Mobject.add (manimlib/mobject/mobject.py:433). A mobject's family is a tree; adding a mobject to itself would create a cycle and corrupt family traversal (get_family, note_changed_family), so manim rejects mob.add(mob) explicitly before touching submobjects.

Source

Thrown at manimlib/mobject/mobject.py:433

        If extended is set to true, it includes the ancestors of all family members,
        e.g. any other parents of a submobject
        """
        ancestors = []
        to_process = list(self.get_family(recurse=extended))
        excluded = set(to_process)
        while to_process:
            for p in to_process.pop().parents:
                if p not in excluded:
                    ancestors.append(p)
                    to_process.append(p)
        # Ensure mobjects highest in the hierarchy show up first
        ancestors.reverse()
        # Remove list redundancies while preserving order
        return list(dict.fromkeys(ancestors))

    def add(self, *mobjects: Mobject) -> Self:
        if self in mobjects:
            raise Exception("Mobject cannot contain self")
        for mobject in mobjects:
            if mobject not in self.submobjects:
                self.submobjects.append(mobject)
            if self not in mobject.parents:
                mobject.parents.append(self)
        self.note_changed_family()
        return self

    def remove(
        self,
        *to_remove: Mobject,
        reassemble: bool = True,
        recurse: bool = True
    ) -> Self:
        for parent in self.get_family(recurse):
            for child in to_remove:
                if child in parent.submobjects:
                    parent.submobjects.remove(child)

View on GitHub (pinned to dee01804d4)

Solutions

  1. Remove the self-referential add: audit callsites for mob.add(mob) or VGroup construction including the group itself
  2. When merging groups, add the OTHER group's submobjects: a.add(*b) or use VGroup(a, b)
  3. Use group.add(*others) only with objects distinct from group

Example fix

# before
group = VGroup()
for shape in shapes:
    group.add(group, shape)  # raises: cannot contain self

# after
group = VGroup()
for shape in shapes:
    group.add(shape)
Defensive patterns

Strategy: validation

Validate before calling

def safe_add(group, *mobs):
    for m in mobs:
        assert m is not group, "cannot add a group to itself"
    group.add(*mobs)

Prevention

When it happens

Trigger: Calling mob.add(mob); passing the same object into its own constructor pattern like vg.add(vg); dynamic code where a group is built from a list that accidentally already contains the group being filled.

Common situations: Accumulating results in-place: group = VGroup(); for x in items: group.add(group) style bugs; splatting a container into itself: group.add(*group) is fine (children, not self), but group.add(group) is not; copy/paste of add boilerplate.

Related errors


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