3b1b/manim · error · Exception
Only VMobjects can be passed into VGroup
Error message
Only VMobjects can be passed into VGroup
What it means
Raised by VGroup.__init__ (vectorized_mobject.py:1397) when any positional argument is an instance of Mobject but not of VMobject. Note the asymmetry with VMobject.add: non-Mobject arguments (e.g. an iterable of VMobjects, which _ingest_args expands) are allowed, but a concrete non-vectorized Mobject is rejected.
Source
Thrown at manimlib/mobject/types/vectorized_mobject.py:1397
about_point: Vect3 | None = None,
**kwargs
) -> Self:
rot_matrix_T = rotation_matrix_transpose(angle, axis)
self.apply_points_function(
lambda points: np.dot(points, rot_matrix_T),
about_point,
**kwargs
)
for mob in self.get_family():
mob.get_unit_normal(refresh=True)
return self
class VGroup(Group, VMobject, Generic[SubVmobjectType]):
def __init__(self, *vmobjects: SubVmobjectType | Iterable[SubVmobjectType], **kwargs):
super().__init__(**kwargs)
if any(isinstance(vmob, Mobject) and not isinstance(vmob, VMobject) for vmob in vmobjects):
raise Exception("Only VMobjects can be passed into VGroup")
self._ingest_args(*vmobjects)
if self.submobjects:
self.uniforms.update(self.submobjects[0].uniforms)
def __add__(self, other: VMobject) -> Self:
assert isinstance(other, VMobject)
return self.add(other)
# This is just here to make linters happy with references to things like VGroup(...)[0]
def __getitem__(self, index) -> SubVmobjectType:
return super().__getitem__(index)
class VectorizedPoint(Point, VMobject):
def __init__(
self,
location: np.ndarray = ORIGIN,
color: ManimColor = BLACK,View on GitHub (pinned to dee01804d4)
Solutions
- Replace the non-VMobject argument with a VMobject equivalent (Group -> VGroup, Point -> a vectorized dot or remove it)
- Use Group(...) instead of VGroup(...) when you genuinely need to hold non-vectorized mobjects
- Unpack iterables explicitly and verify each element with isinstance(m, VMobject) before constructing the VGroup
Example fix
# before inner = Group(Dot(), Circle()) outer = VGroup(inner) # Group is a Mobject, not a VMobject -> raises # after inner = VGroup(Dot(), Circle()) outer = VGroup(inner)
Defensive patterns
Strategy: type-guard
Validate before calling
flat = []
for arg in args:
flat.extend(arg if isinstance(arg, (list, tuple)) else [arg])
assert all(isinstance(m, VMobject) for m in flat)
vg = VGroup(*flat) Type guard
from manimlib import VMobject, Mobject
def is_vmobject(m) -> bool:
return isinstance(m, VMobject) and not (isinstance(m, Mobject) and not isinstance(m, VMobject)) Prevention
- Nest VMobjects only: convert Group -> VGroup before putting it inside a VGroup
- Unpack iterables explicitly so every element is a VMobject
- Run isinstance(m, VMobject) checks in helper builders that assemble VGroups dynamically
When it happens
Trigger: VGroup(Group(...)), VGroup(Mobject()), VGroup(Point(...), Dot()) (Point is not a VMobject), or VGroup(Points()/a PMobject). Passing a plain list [Dot(), Dot()] does NOT raise because a list is not a Mobject; it is ingested instead.
Common situations: Nesting a Group inside VGroup for organizational purposes; passing a mixed list where one element is an ImageMobject or point-cloud mobject; copy-pasting Group construction into VGroup code during refactors.
Related errors
- All submobjects must be of type VMobject
- All submobjects must be of type PMobject
- Must specify either a file_name or svg_string SVGMobject
- Invalid color type
- Unsupported: {path_verb}
AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14).
Data as JSON: /api/errors/5e1c2c65abce6e13.
Report an issue: GitHub.