{"record":{"id":"7b3ec8a54f3f2db2","repo":"Textualize/textual","slug":"no-common-ancestor-found","errorCode":null,"errorMessage":"No common ancestor found","messagePattern":"No common ancestor found","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/textual/widget.py","lineNumber":718,"sourceCode":"            ValueError: If there is no common ancestor and `default` is not provided (will not occur if both widgets are attached to the same DOM).\n\n        Args:\n            widget1: A Widget.\n            widget2: A second widgets.\n            default: A widget to return if no common ancestor is found.\n\n        Returns:\n            A common ancestor widgets.\n        \"\"\"\n        ancestors1 = widget1.ancestors\n        ancestors2 = set(widget2.ancestors)\n        for node in ancestors1:\n            if node in ancestors2:\n                assert isinstance(node, Widget)\n                return node\n        if default is not None:\n            return default\n        raise ValueError(\"No common ancestor found\")\n\n    def focus_on_click(self) -> bool:\n        \"\"\"Automatically focus the widget on click?\n\n        Implement this if you want to change the default click to focus behavior.\n        The default will return the classvar `FOCUS_ON_CLICK`.\n\n        Returns:\n            `True` if Textual should set focus automatically on a click, or `False` if it shouldn't.\n        \"\"\"\n        return self.FOCUS_ON_CLICK\n\n    def get_line_filters(self) -> Sequence[LineFilter]:\n        \"\"\"Get the line filters enabled for this widget.\n\n        Returns:\n            A sequence of [LineFilter][textual.filters.LineFilter] instances.\n        \"\"\"","sourceCodeStart":700,"sourceCodeEnd":736,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widget.py#L700-L736","documentation":"get_commonancestor walks both widgets' ancestor chains looking for a shared node; if none exists (different trees) and no default was supplied, it raises ValueError.","triggerScenarios":"Calling widget.get_common_ancestor(other) where one widget is mounted and the other is not, or they live under different roots (e.g. two separate screens or an unmounted subtree).","commonSituations":"Comparing widgets during mount/unmount transitions, or widgets from a modal screen vs the base screen.","solutions":["Pass a default: get_common_ancestor(other, default=app) or default=None","Ensure both widgets are mounted under the same root before comparing","Check 'widget.is_attached' on both first"],"exampleFix":"# before\nancestor = a.get_common_ancestor(b)\n# after\nancestor = a.get_common_ancestor(b, default=None)\nif ancestor is None:\n    return","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    anc = a.get_common_ancestor(b)\nexcept ValueError:\n    anc = None","preventionTips":["Pass default= for cross-tree comparisons","Verify both widgets are attached before comparing"],"tags":["dom-tree","widget","textual"],"backgroundTag":"no-common-ancestor","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}