{"record":{"id":"4c4ab3d0327bb3ab","repo":"donnemartin/interactive-coding-challenges","slug":"root-must-have-at-least-one-child","errorCode":null,"errorMessage":"root must have at least one child","messagePattern":"root must have at least one child","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"graphs_trees/bst_second_largest/bst_second_largest_solution.ipynb","lineNumber":160,"sourceCode":"    \"        if node.right is not None:\\n\",\n    \"            if node.right.left is not None or node.right.right is not None:\\n\",\n    \"                return self._find_second_largest(node.right)\\n\",\n    \"            else:\\n\",\n    \"                return node\\n\",\n    \"        else:\\n\",\n    \"            return self._find_right_most_node(node.left)\\n\",\n    \"\\n\",\n    \"    def _find_right_most_node(self, node):\\n\",\n    \"        if node.right is not None:\\n\",\n    \"            return self._find_right_most_node(node.right)\\n\",\n    \"        else:\\n\",\n    \"            return node\\n\",\n    \"\\n\",\n    \"    def find_second_largest(self):\\n\",\n    \"        if self.root is None:\\n\",\n    \"            raise TypeError('root cannot be None')\\n\",\n    \"        if self.root.right is None and self.root.left is None:\\n\",\n    \"            raise ValueError('root must have at least one child')\\n\",\n    \"        return self._find_second_largest(self.root)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/graphs_trees/bst_second_largest/bst_second_largest_solution.ipynb#L142-L178","documentation":"Bst.find_second_largest raises ValueError('root must have at least one child') when the tree consists of a single node (root with no left and no right child). With only one node there is no second largest element, so the state is invalid rather than merely empty.","triggerScenarios":"bst.insert(5); bst.find_second_largest() on a tree containing exactly one node — root.right is None and root.left is None.","commonSituations":"Querying small datasets, early in ingestion when only one record has arrived, or test cases that only insert a single element.","solutions":["Insert at least two elements before calling find_second_largest()","Guard the call: check tree.root and one of tree.root.left/tree.root.right exist first","Wrap with your own accessor that returns None for single-node trees"],"exampleFix":"# before\nbst.insert(10)\nsecond = bst.find_second_largest()  # only one node\n\n# after\nbst.insert(10)\nbst.insert(4)\nsecond = bst.find_second_largest()","handlingStrategy":"validation","validationCode":"root = bst.root\nif root is None or (root.left is None and root.right is None):\n    return None  # fewer than two nodes\nbst.find_second_largest()","typeGuard":"def has_at_least_two_nodes(t) -> bool:\n    return t.root is not None and (t.root.left is not None or t.root.right is not None)","tryCatchPattern":"try:\n    second = bst.find_second_largest()\nexcept ValueError as e:\n    if 'at least one child' in str(e):\n        second = None\n    else:\n        raise","preventionTips":["Require >= 2 inserts before second-largest queries","Guard single-node trees with a root-child check","Design wrappers that return None instead of raising for small inputs"],"tags":["python","bst","tree","insufficient-data","value-error"],"backgroundTag":"empty-collection-operation","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}