{"record":{"id":"2f4b5a3264464495","repo":"3b1b/manim","slug":"all-submobjects-must-be-of-type-vmobject","errorCode":null,"errorMessage":"All submobjects must be of type VMobject","messagePattern":"All submobjects must be of type VMobject","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"manimlib/mobject/types/vectorized_mobject.py","lineNumber":245,"sourceCode":"            stroke_width_in_scene_units=float(self.stroke_width_in_scene_units),\n            # A filled VMobject is taken to be flat, which is what lets its normal\n            # be one value rather than one per point, and what makes the winding\n            # count deciding its interior meaningful in the first place\n            unit_normal=np.array(OUT, dtype=float),\n            # A fill is one flat region of one color, so unlike stroke there is\n            # nothing for a per point value to mean\n            fill_rgba=np.zeros(4),\n            # A second color, equal to the first unless a gradient was asked for,\n            # along with the two points it runs between, see inserts/fill_color.wgsl\n            fill_rgba_end=np.zeros(4),\n            gradient_start=np.zeros(3),\n            gradient_end=np.zeros(3),\n            fill_border_width=float(self.fill_border_width),\n        )\n\n    def add(self, *vmobjects: VMobject) -> Self:\n        if not all((isinstance(m, VMobject) for m in vmobjects)):\n            raise Exception(\"All submobjects must be of type VMobject\")\n        return super().add(*vmobjects)\n\n    # Colors\n    def init_colors(self):\n        self.set_stroke(\n            color=self.stroke_color,\n            width=self.stroke_width,\n            opacity=self.stroke_opacity,\n            behind=self.stroke_behind,\n        )\n        self.set_fill(\n            color=self.fill_color,\n            opacity=self.fill_opacity,\n            border_width=self.fill_border_width,\n        )\n        self.set_shading(*self.shading)\n        self.set_flat_stroke(self.flat_stroke)\n        self.color = self.get_color()","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/3b1b/manim/blob/dee01804d47b9f94402d71472674710dcac125b8/manimlib/mobject/types/vectorized_mobject.py#L227-L263","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nvg = VGroup()\nvg.add(Group(Dot(), Dot()))  # Group is not a VMobject -> raises\n\n# after\nvg = VGroup()\nvg.add(Dot(), Dot())","handlingStrategy":"type-guard","validationCode":"vmobs = [m for m in candidates if isinstance(m, VMobject)]\ncontainer.add(*vmobs)","typeGuard":"from manimlib.mobject.types.vectorized_mobject import VMobject\n\ndef all_vmobjects(mobs) -> bool:\n    return all(isinstance(m, VMobject) for m in mobs)","tryCatchPattern":null,"preventionTips":["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()"],"tags":["manim","vgroup","type-check","vmobject"],"backgroundTag":null,"analyzedSha":"dee01804d47b9f94402d71472674710dcac125b8","analyzedAt":"2026-08-14T19:53:44.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}