Textualize/textual · error · AddNodeError
Unable to add a node both before and after a node
Error message
Unable to add a node both before and after a node
What it means
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.
Source
Thrown at src/textual/widgets/_tree.py:390
label: The new node's label.
data: Data associated with the new node.
before: Optional index or `TreeNode` to add the node before.
after: Optional index or `TreeNode` to add the node after.
expand: Node should be expanded.
allow_expand: Allow user to expand the node via keyboard or mouse.
Returns:
A new Tree node
Raises:
AddNodeError: If there is a problem with the addition request.
Note:
Only one of `before` or `after` can be provided. If both are
provided a `AddNodeError` will be raised.
"""
if before is not None and after is not None:
raise AddNodeError("Unable to add a node both before and after a node")
insert_index: int = len(self.children)
if before is not None:
if isinstance(before, int):
insert_index = before
elif isinstance(before, TreeNode):
try:
insert_index = self.children.index(before)
except ValueError:
raise AddNodeError(
"The node specified for `before` is not a child of this node"
)
else:
raise TypeError(
"`before` argument must be an index or a TreeNode object to add before"
)
View on GitHub (pinned to 06dbeef4bb)
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.
Example fix
# before
node.add("item", before=2, after=3)
# after
node.add("item", before=2) Defensive patterns
Strategy: validation
Validate before calling
assert not (before is not None and after is not None), "pass only one of before/after" node.add(label, before=before, after=after)
Try / catch
from textual.widgets._tree import AddNodeError
try:
node.add(label, before=b, after=a)
except AddNodeError:
node.add(label) # append Prevention
- Pass at most one positioning keyword
- Lint calls that forward **pos dicts to add()
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The node specified for `before` is not a child of this node
- `before` argument must be an index or a TreeNode object to a
- The node specified for `after` is not a child of this node
- `after` argument must be an index or a TreeNode object to ad
- Attempt to remove the root node of a Tree.
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/26beb5b5f11a9f2e.
Report an issue: GitHub.