Textualize/textual · error · AddNodeError

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

Error message

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

What it means

AddNodeError from TreeNode.add(): the `after` argument is a TreeNode that is not a child of this node, so its index (needed to compute insert position index+1) cannot be found.

Source

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

                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"
                    )
            else:
                raise TypeError(
                    "`after` argument must be an index or a TreeNode object to add after"
                )

        text_label = self._tree.process_label(label)
        node = self._tree._add_node(self, text_label, data)
        node._expanded = expand
        node._allow_expand = allow_expand
        self._updates += 1
        self._children.insert(insert_index, node)
        self._tree._invalidate()

        return node

    def add_leaf(

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Check `after_node in node.children` before calling add.
  2. Re-query the node from the tree after any structural mutation.
  3. Insert via the target node's actual parent: `after_node.parent.add("x", after=after_node)`.

Example fix

# before
node.add("new", after=stale_node)
# after
if target in node.children:
    node.add("new", after=target)
Defensive patterns

Strategy: validation

Validate before calling

if after is not None and after not in node.children:
    after = None
node.add(label, after=after)

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, after=ref)
except AddNodeError:
    node.add(label)

Prevention

When it happens

Trigger: `node.add("x", after=some_node)` where some_node has a different parent, was removed, or belongs to another subtree.

Common situations: Reusing TreeNode references captured before a `clear()`/reload; appending after a node obtained from `tree.get_node_by_id` under a different branch.

Related errors


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