{"record":{"id":"b213cc4066806d9b","repo":"TheAlgorithms/Python","slug":"value-value-not-found","errorCode":null,"errorMessage":"Value {value} not found","messagePattern":"Value (.+?) not found","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"data_structures/binary_tree/binary_search_tree.py","lineNumber":285,"sourceCode":"        >>> BinarySearchTree().insert(1, 783, 30, 740, 1).get_min()\n        {'1': (None, {'783': ({'30': (1, 740)}, None)})}\n        \"\"\"\n        if node is None:\n            node = self.root\n        if self.root is None:\n            return None\n        if not self.empty():\n            node = self.root\n            while node.left is not None:\n                node = node.left\n        return node\n\n    def remove(self, value: int) -> None:\n        # Look for the node with that label\n        node = self.search(value)\n        if node is None:\n            msg = f\"Value {value} not found\"\n            raise ValueError(msg)\n\n        if node.left is None and node.right is None:  # If it has no children\n            self.__reassign_nodes(node, None)\n        elif node.left is None:  # Has only right children\n            self.__reassign_nodes(node, node.right)\n        elif node.right is None:  # Has only left children\n            self.__reassign_nodes(node, node.left)\n        else:\n            predecessor = self.get_max(\n                node.left\n            )  # Gets the max value of the left branch\n            self.remove(predecessor.value)  # type: ignore[union-attr]\n            node.value = (\n                predecessor.value  # type: ignore[union-attr]\n            )  # Assigns the value to the node to delete and keep tree structure\n\n    def preorder_traverse(self, node: Node | None) -> Iterable:\n        if node is not None:","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/data_structures/binary_tree/binary_search_tree.py#L267-L303","documentation":"Raised by BinarySearchTree.remove() in data_structures/binary_tree/binary_search_tree.py when search(value) returns None — the value is not present in the tree. remove() locates the node first and refuses to silently no-op, raising ValueError with the missing value in the message.","triggerScenarios":"Calling remove(42) on a tree that does not contain 42; also removing an already-removed value, or removing from an empty tree (search raises IndexError first in that case — the not-found path applies once the tree has nodes).","commonSituations":"Double-removal in UIs (two delete clicks for the same item), bulk deletion where the source list contains duplicates the tree does not, or cleanup code that assumes a value exists without checking.","solutions":["Check membership before removing: use `if value in tree` (or search) and skip when absent.","Wrap remove in try/except ValueError for bulk operations where absence is expected.","Make delete handlers idempotent so a second delete of the same value is a no-op."],"exampleFix":"# before\ntree.remove(42)  # 42 not in tree\n\n# after\nif 42 in tree:\n    tree.remove(42)","handlingStrategy":"try-catch","validationCode":"if value in tree:\n    tree.remove(value)","typeGuard":null,"tryCatchPattern":"try:\n    tree.remove(value)\nexcept ValueError as e:\n    if 'not found' in str(e):\n        pass  # idempotent delete\n    else:\n        raise","preventionTips":["Make delete handlers idempotent","Check membership before removing in bulk operations","Deduplicate deletion lists before applying them to the tree"],"tags":["value-validation","binary-tree","bst","delete"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}