3b1b/manim · error · Exception
All submobjects must be of type VMobject
Error message
All submobjects must be of type VMobject
What it means
Raised by VMobject.add (vectorized_mobject.py:245) when any argument passed to .add() is not an instance of VMobject. VMobject-only containers (vectorized mobjects rendered with stroke/fill shaders) cannot hold arbitrary Mobjects such as point-cloud PMobjects or bare Mobjects, so the type is enforced on every add call.
Source
Thrown at manimlib/mobject/types/vectorized_mobject.py:245
stroke_width_in_scene_units=float(self.stroke_width_in_scene_units),
# A filled VMobject is taken to be flat, which is what lets its normal
# be one value rather than one per point, and what makes the winding
# count deciding its interior meaningful in the first place
unit_normal=np.array(OUT, dtype=float),
# A fill is one flat region of one color, so unlike stroke there is
# nothing for a per point value to mean
fill_rgba=np.zeros(4),
# A second color, equal to the first unless a gradient was asked for,
# along with the two points it runs between, see inserts/fill_color.wgsl
fill_rgba_end=np.zeros(4),
gradient_start=np.zeros(3),
gradient_end=np.zeros(3),
fill_border_width=float(self.fill_border_width),
)
def add(self, *vmobjects: VMobject) -> Self:
if not all((isinstance(m, VMobject) for m in vmobjects)):
raise Exception("All submobjects must be of type VMobject")
return super().add(*vmobjects)
# Colors
def init_colors(self):
self.set_stroke(
color=self.stroke_color,
width=self.stroke_width,
opacity=self.stroke_opacity,
behind=self.stroke_behind,
)
self.set_fill(
color=self.fill_color,
opacity=self.fill_opacity,
border_width=self.fill_border_width,
)
self.set_shading(*self.shading)
self.set_flat_stroke(self.flat_stroke)
self.color = self.get_color()View on GitHub (pinned to dee01804d4)
Solutions
- Add only VMobject instances; convert the offending item to a VMobject type (e.g. use VGroup instead of Group, or wrap non-vectorized content appropriately)
- If you need to mix non-VMobject mobjects, use the generic Mobject.add / Group container instead of a VMobject/VGroup container
- Check types before adding: filter with isinstance(m, VMobject) to find which element fails
Example fix
# before vg = VGroup() vg.add(Group(Dot(), Dot())) # Group is not a VMobject -> raises # after vg = VGroup() vg.add(Dot(), Dot())
Defensive patterns
Strategy: type-guard
Validate before calling
vmobs = [m for m in candidates if isinstance(m, VMobject)] container.add(*vmobs)
Type guard
from manimlib.mobject.types.vectorized_mobject import VMobject
def all_vmobjects(mobs) -> bool:
return all(isinstance(m, VMobject) for m in mobs) Prevention
- Only call .add() on VMobject containers with VMobject arguments
- Use Group when mixing vectorized and non-vectorized mobjects
- Filter lists through isinstance(m, VMobject) before add()
When it happens
Trigger: Calling some_vgroup.add(Dot()) is fine; raising calls include dot.add(PMobject-instance), vgroup.add(Mobject()), or adding a Group (which is an Mobject but not a VMobject) into a VMobject: VGroup().add(Group(Dot())) raises.
Common situations: Mixing Mobject subclasses into a VGroup via .add() instead of the constructor; refactoring code that used generic Mobject containers; passing a Group of images or a Point (non-vectorized mobject) into a VGroup-based scene layout.
Related errors
- Only VMobjects can be passed into VGroup
- Cannot call Mobject.{} for a Mobject with no points
- All submobjects must be of type PMobject
- Invalid color type
- Unsupported: {path_verb}
AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14).
Data as JSON: /api/errors/2f4b5a3264464495.
Report an issue: GitHub.