TheAlgorithms/Python · error · ValueError

Node with label {label} already exists

Error message

Node with label {label} already exists

What it means

Raised by BinarySearchTree.put() (via _put) when inserting a label that already exists in the tree. This recursive BST implementation stores unique keys only: the _put recursion compares label against node.label and hits the else branch on equality, raising ValueError. It is a duplicate-key guard, matching the semantics of dict assignment but refusing silent overwrite.

Source

Thrown at data_structures/binary_tree/binary_search_tree_recursive.py:83

        >>> assert t.root.right.parent == t.root
        >>> assert t.root.right.label == 10

        >>> t.put(3)
        >>> assert t.root.left.parent == t.root
        >>> assert t.root.left.label == 3
        """
        self.root = self._put(self.root, label)

    def _put(self, node: Node | None, label: int, parent: Node | None = None) -> Node:
        if node is None:
            node = Node(label, parent)
        elif label < node.label:
            node.left = self._put(node.left, label, node)
        elif label > node.label:
            node.right = self._put(node.right, label, node)
        else:
            msg = f"Node with label {label} already exists"
            raise ValueError(msg)

        return node

    def search(self, label: int) -> Node:
        """
        Searches a node in the tree

        >>> t = BinarySearchTree()
        >>> t.put(8)
        >>> t.put(10)
        >>> node = t.search(8)
        >>> assert node.label == 8

        >>> node = t.search(3)
        Traceback (most recent call last):
            ...
        ValueError: Node with label 3 does not exist
        """

View on GitHub (pinned to f5988cc097)

Solutions

  1. Deduplicate input before insertion: `for label in dict.fromkeys(labels): t.put(label)`
  2. Check membership first: `if not t.exists(label): t.put(label)` (or guard with a search/try except)
  3. Wrap the put call in try/except ValueError and ignore duplicates if overwrite semantics are acceptable
  4. If duplicates must be stored, switch to a multiset-style structure or store counts in node payloads

Example fix

# before
for v in [8, 10, 8]:
    t.put(v)  # ValueError on second 8

# after
for v in dict.fromkeys([8, 10, 8]):
    t.put(v)
Defensive patterns

Strategy: validation

Validate before calling

from data_structures.binary_tree.binary_search_tree_recursive import BinarySearchTree

def safe_put(t: BinarySearchTree, label: int) -> bool:
    try:
        t.search(label)
        return False  # already present
    except ValueError:
        t.put(label)
        return True

Try / catch

try:
    t.put(label)
except ValueError as e:
    if "already exists" not in str(e):
        raise
    # treat as no-op duplicate

Prevention

When it happens

Trigger: Calling t.put(x) a second time with the same integer x, e.g. t.put(8); t.put(8). Also any bulk-insert loop over data containing repeated values (duplicates in an input list fed to put in a loop).

Common situations: Loading a dataset with duplicate values into the tree; re-running initialization code against an already-populated tree; off-by-one loops that re-insert the last element.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/e2628914c3f42df7. Report an issue: GitHub.