Textualize/textual · error · AddNodeError

The node specified for `before` is not a child of this node

Error message

The node specified for `before` is not a child of this node

What it means

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.

Source

Thrown at src/textual/widgets/_tree.py:401

            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"
                )

        if after is not None:
            if isinstance(after, int):
                insert_index = after + 1
                if after < 0:
                    insert_index += len(self.children)
            elif isinstance(after, TreeNode):
                try:
                    insert_index = self.children.index(after) + 1
                except ValueError:
                    raise AddNodeError(
                        "The node specified for `after` is not a child of this node"

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Verify membership first: `if before_node in node.children: ...`.
  2. Re-fetch the reference after tree mutations (clear/reload) before inserting.
  3. Insert into the correct parent: call `before_node.parent.add(...)` instead.

Example fix

# before
root.add("new", before=stale_node)
# after
parent = tree.get_node_by_id(stale_id)
if parent is not None and target in parent.children:
    parent.add("new", before=target)
Defensive patterns

Strategy: validation

Validate before calling

if before is not None and before not in node.children:
    before = None  # or raise your own error
node.add(label, before=before)

Type guard

from textual.widgets._tree import TreeNode
def is_child(parent: TreeNode, n: object) -> bool:
    return isinstance(n, TreeNode) and n in parent.children

Try / catch

from textual.widgets._tree import AddNodeError
try:
    node.add(label, before=ref)
except AddNodeError:
    node.add(label)

Prevention

When it happens

Trigger: `node.add("x", before=some_node)` where some_node belongs to a different parent, was already removed, or is the node itself.

Common situations: 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.

Related errors


AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27). Data as JSON: /api/errors/e0daa8d19ab46515. Report an issue: GitHub.