{"record":{"id":"9ace5024b9078858","repo":"3b1b/manim","slug":"tip-not-found","errorCode":null,"errorMessage":"tip not found","messagePattern":"tip not found","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"manimlib/mobject/geometry.py","lineNumber":175,"sourceCode":"\n    def get_tips(self) -> VGroup:\n        \"\"\"\n        Returns a VGroup (collection of VMobjects) containing\n        the TipableVMObject instance's tips.\n        \"\"\"\n        result = VGroup()\n        if hasattr(self, \"tip\"):\n            result.add(self.tip)\n        if hasattr(self, \"start_tip\"):\n            result.add(self.start_tip)\n        return result\n\n    def get_tip(self) -> ArrowTip:\n        \"\"\"Returns the TipableVMobject instance's (first) tip,\n        otherwise throws an exception.\"\"\"\n        tips = self.get_tips()\n        if len(tips) == 0:\n            raise Exception(\"tip not found\")\n        else:\n            return tips[0]\n\n    def get_default_tip_length(self) -> float:\n        return self.tip_length\n\n    def get_first_handle(self) -> Vect3:\n        return self.get_points()[1]\n\n    def get_last_handle(self) -> Vect3:\n        return self.get_points()[-2]\n\n    def get_end(self) -> Vect3:\n        if self.has_tip():\n            return self.tip.get_start()\n        else:\n            return VMobject.get_end(self)\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/3b1b/manim/blob/dee01804d47b9f94402d71472674710dcac125b8/manimlib/mobject/geometry.py#L157-L193","documentation":"Raised by TipableVMobject.get_tip (manimlib/mobject/geometry.py:175) when get_tips() returns an empty list — the mobject has neither a 'tip' nor a 'start_tip' attribute. Tips are created by add_tip() (or automatically by Arrow), so a TipableVMobject that never gained a tip has nothing to return.","triggerScenarios":"Calling get_tip() on a TipableVMobject subclass (e.g. Line used directly) without ever calling add_tip(); deleting/removing the tip from an Arrow then calling get_tip(); calling get_angle()/get_tip() helpers that internally rely on get_tip().","commonSituations":"Using Line instead of Arrow and then calling get_tip() for angle computation; writing generic code over vector-like mobjects where some have tips and some don't; removing tips after style changes.","solutions":["Use an Arrow (which auto-creates a tip) or call mob.add_tip() before get_tip()","Use get_tips() and check the result length instead of get_tip()","Use hasattr(self, 'tip') / isinstance checks before tip-dependent logic"],"exampleFix":"# before\nangle = line.get_tip()  # raises: tip not found for plain Line\n\n# after\nangle = line.get_angle()  # or:\ntips = line.get_tips()\nif tips:\n    angle = tips[0].get_angle()","handlingStrategy":"validation","validationCode":"tips = mob.get_tips()\nif len(tips) == 0:\n    raise ValueError(\"no tip present; call add_tip() or use Arrow\")\ntip = tips[0]","typeGuard":"def has_tip(mob) -> bool:\n    return len(mob.get_tips()) > 0","tryCatchPattern":"try:\n    tip = mob.get_tip()\nexcept Exception as e:\n    if \"tip not found\" in str(e):\n        tip = None  # handle tip-less vectors gracefully\n    else:\n        raise","preventionTips":["Prefer get_tips() over get_tip() in generic code","Use Arrow instead of Line when tip-dependent logic follows"],"tags":["manim","geometry","arrow","tips"],"backgroundTag":null,"analyzedSha":"dee01804d47b9f94402d71472674710dcac125b8","analyzedAt":"2026-08-14T19:53:44.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}