{"record":{"id":"e0daa8d19ab46515","repo":"Textualize/textual","slug":"the-node-specified-for-before-is-not-a-child-of","errorCode":null,"errorMessage":"The node specified for `before` is not a child of this node","messagePattern":"The node specified for `before` is not a child of this node","errorType":"exception","errorClass":"AddNodeError","httpStatus":null,"severity":"error","filePath":"src/textual/widgets/_tree.py","lineNumber":401,"sourceCode":"            AddNodeError: If there is a problem with the addition request.\n\n        Note:\n            Only one of `before` or `after` can be provided. If both are\n            provided a `AddNodeError` will be raised.\n        \"\"\"\n        if before is not None and after is not None:\n            raise AddNodeError(\"Unable to add a node both before and after a node\")\n\n        insert_index: int = len(self.children)\n\n        if before is not None:\n            if isinstance(before, int):\n                insert_index = before\n            elif isinstance(before, TreeNode):\n                try:\n                    insert_index = self.children.index(before)\n                except ValueError:\n                    raise AddNodeError(\n                        \"The node specified for `before` is not a child of this node\"\n                    )\n            else:\n                raise TypeError(\n                    \"`before` argument must be an index or a TreeNode object to add before\"\n                )\n\n        if after is not None:\n            if isinstance(after, int):\n                insert_index = after + 1\n                if after < 0:\n                    insert_index += len(self.children)\n            elif isinstance(after, TreeNode):\n                try:\n                    insert_index = self.children.index(after) + 1\n                except ValueError:\n                    raise AddNodeError(\n                        \"The node specified for `after` is not a child of this node\"","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widgets/_tree.py#L383-L419","documentation":"AddNodeError from TreeNode.add(): the `before` argument is a TreeNode that is not in this node's `children` list, so `list.index()` fails and no insertion position can be determined.","triggerScenarios":"`node.add(\"x\", before=some_node)` where some_node belongs to a different parent, was already removed, or is the node itself.","commonSituations":"Holding stale TreeNode references after the tree was rebuilt/cleared via `clear()` or `remove_children()`, or inserting relative to a node found via `get_node_by_id` from a different subtree.","solutions":["Verify membership first: `if before_node in node.children: ...`.","Re-fetch the reference after tree mutations (clear/reload) before inserting.","Insert into the correct parent: call `before_node.parent.add(...)` instead."],"exampleFix":"# before\nroot.add(\"new\", before=stale_node)\n# after\nparent = tree.get_node_by_id(stale_id)\nif parent is not None and target in parent.children:\n    parent.add(\"new\", before=target)","handlingStrategy":"validation","validationCode":"if before is not None and before not in node.children:\n    before = None  # or raise your own error\nnode.add(label, before=before)","typeGuard":"from textual.widgets._tree import TreeNode\ndef is_child(parent: TreeNode, n: object) -> bool:\n    return isinstance(n, TreeNode) and n in parent.children","tryCatchPattern":"from textual.widgets._tree import AddNodeError\ntry:\n    node.add(label, before=ref)\nexcept AddNodeError:\n    node.add(label)","preventionTips":["Invalidate stored TreeNode refs after clear()/reload","Insert via target.parent to guarantee membership"],"tags":["tree","stale-reference","insert","textual"],"backgroundTag":"stale-node-reference","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}