{"record":{"id":"26beb5b5f11a9f2e","repo":"Textualize/textual","slug":"unable-to-add-a-node-both-before-and-after-a-node","errorCode":null,"errorMessage":"Unable to add a node both before and after a node","messagePattern":"Unable to add a node both before and after a node","errorType":"exception","errorClass":"AddNodeError","httpStatus":null,"severity":"error","filePath":"src/textual/widgets/_tree.py","lineNumber":390,"sourceCode":"            label: The new node's label.\n            data: Data associated with the new node.\n            before: Optional index or `TreeNode` to add the node before.\n            after: Optional index or `TreeNode` to add the node after.\n            expand: Node should be expanded.\n            allow_expand: Allow user to expand the node via keyboard or mouse.\n\n        Returns:\n            A new Tree node\n\n        Raises:\n            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","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widgets/_tree.py#L372-L408","documentation":"TreeNode.add() raises AddNodeError when both `before` and `after` keyword arguments are supplied. Position is ambiguous, so the API refuses to guess where to insert the new node.","triggerScenarios":"Calling `node.add(\"label\", before=x, after=y)` (or add_node with both) — both arguments must be None/int/TreeNode, and at most one may be given.","commonSituations":"Copy-pasting insertion code and forgetting to delete one keyword; dynamic code that passes a positioning dict like `node.add(label, **pos)` where pos contains both keys.","solutions":["Pass only one of `before` or `after`.","If position comes from a variable, default the other to None: `node.add(label, before=pos_before, after=pos_after)` where at least one is None."],"exampleFix":"# before\nnode.add(\"item\", before=2, after=3)\n# after\nnode.add(\"item\", before=2)","handlingStrategy":"validation","validationCode":"assert not (before is not None and after is not None), \"pass only one of before/after\"\nnode.add(label, before=before, after=after)","typeGuard":null,"tryCatchPattern":"from textual.widgets._tree import AddNodeError\ntry:\n    node.add(label, before=b, after=a)\nexcept AddNodeError:\n    node.add(label)  # append","preventionTips":["Pass at most one positioning keyword","Lint calls that forward **pos dicts to add()"],"tags":["tree","insert","argument-validation","textual"],"backgroundTag":"conflicting-arguments","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}