3b1b/manim · error · Exception

Invalid argument to Group of type {type(args[0])}

Error message

Invalid argument to Group of type {type(args[0])}

What it means

Formatted Exception from Group._ingest_args (manimlib/mobject/mobject.py:2100): 'Invalid argument to Group of type {type(args[0])}'. Group accepts either several Mobject instances or a single iterable of Mobjects; anything else — an int, a string, a dict, None — falls to the else branch. (Note: a str IS iterable, so Group("ab") would instead try add('a','b') and fail differently; the raise fires for non-iterable, non-Mobject first args.)

Source

Thrown at manimlib/mobject/mobject.py:2100

                      "for a Mobject with no points"
            caller_name = sys._getframe(1).f_code.co_name
            raise Exception(message.format(caller_name))


class Group(Mobject, Generic[SubmobjectType]):
    def __init__(self, *mobjects: SubmobjectType | Iterable[SubmobjectType], **kwargs):
        super().__init__(**kwargs)
        self._ingest_args(*mobjects)

    def _ingest_args(self, *args: Mobject | Iterable[Mobject]):
        if len(args) == 0:
            return
        if all(isinstance(mob, Mobject) for mob in args):
            self.add(*args)
        elif isinstance(args[0], Iterable):
            self.add(*args[0])
        else:
            raise Exception(f"Invalid argument to Group of type {type(args[0])}")

    def __add__(self, other: Mobject | Group) -> Self:
        assert isinstance(other, Mobject)
        return self.add(other)

    # This is just here to make linters happy with references to things like Group(...)[0]
    def __getitem__(self, index) -> SubmobjectType:
        return super().__getitem__(index)


class Point(Mobject):
    def __init__(
        self,
        location: Vect3 = ORIGIN,
        artificial_width: float = 1e-6,
        artificial_height: float = 1e-6,
        **kwargs
    ):

View on GitHub (pinned to dee01804d4)

Solutions

  1. Flatten arguments before constructing: Group(*all_mobjects) where every element is a Mobject
  2. Wrap scalars/optionals: Group(m) if m is not None else Group(); never pass ints/None/bools
  3. Do not mix one Mobject with a list — Group(m, *others) or Group(m, VGroup(*others))

Example fix

# before
g = Group(count)              # count is an int -> raises
g = Group(mob, [mob2, mob3])  # mixed -> raises (args[0] is Mobject, not iterable-of-check)

# after
g = Group(mob, mob2, mob3)    # all Mobjects
# or
g = Group(mob, *[mob2, mob3])
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import Iterable
from manimlib.mobject.mobject import Mobject

def build_group(*args):
    mobs = []
    for a in args:
        if isinstance(a, Mobject):
            mobs.append(a)
        elif isinstance(a, Iterable) and not isinstance(a, str):
            mobs.extend(a)
        else:
            raise TypeError(f"cannot add {a!r} of type {type(a).__name__} to a Group")
    return Group(*mobs)

Type guard

def is_group_arg(obj) -> bool:
    return isinstance(obj, Mobject) or (isinstance(obj, Iterable) and not isinstance(obj, str))

Prevention

When it happens

Trigger: Group(5), Group(None), Group(True); passing a numpy array of mobjects is accepted (iterable), but passing an unwrapped scalar or an object that is neither Mobject nor Iterable raises; mixed args like Group(mob, [mob2]) fall into the else because not all are Mobjects and args[0] is a Mobject... in that case args[0] IS a Mobject but not Iterable — actually isinstance(Mobject, Iterable) is False, so Group(mob, [mob2]) also raises with type of args[0].

Common situations: Passing a count or index by mistake (Group(len(items))); passing keyword-style scalars; mixing a single mobject with a list in the same call; API refactor changing a function to return a scalar that gets forwarded to Group.

Related errors


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