donnemartin/interactive-coding-challenges · error · TypeError
root cannot be None
Error message
root cannot be None
What it means
Bst.find_second_largest raises TypeError('root cannot be None') when called on an empty tree (self.root is None). Finding the second largest node requires at least one existing node, so an empty tree is an invalid state for this operation.
Source
Thrown at graphs_trees/bst_second_largest/bst_second_largest_solution.ipynb:158
"\n",
" def _find_second_largest(self, node):\n",
" if node.right is not None:\n",
" if node.right.left is not None or node.right.right is not None:\n",
" return self._find_second_largest(node.right)\n",
" else:\n",
" return node\n",
" else:\n",
" return self._find_right_most_node(node.left)\n",
"\n",
" def _find_right_most_node(self, node):\n",
" if node.right is not None:\n",
" return self._find_right_most_node(node.right)\n",
" else:\n",
" return node\n",
"\n",
" def find_second_largest(self):\n",
" if self.root is None:\n",
" raise TypeError('root cannot be None')\n",
" if self.root.right is None and self.root.left is None:\n",
" raise ValueError('root must have at least one child')\n",
" return self._find_second_largest(self.root)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{View on GitHub (pinned to 358f2cc604)
Solutions
- Populate the tree with at least one insert() before calling find_second_largest()
- Guard the call: if tree.root is None: handle empty-tree case
- Return a sentinel (e.g. None) for empty trees by wrapping the call in your own method
Example fix
# before
bst = Bst()
second = bst.find_second_largest() # empty tree
# after
bst = Bst()
for x in (10, 5, 20):
bst.insert(x)
second = bst.find_second_largest() if bst.root else None Defensive patterns
Strategy: validation
Validate before calling
if bst.root is None:
return None # or raise your own 'tree is empty' error
bst.find_second_largest() Type guard
def is_non_empty_tree(t) -> bool:
return t is not None and t.root is not None Try / catch
try:
second = bst.find_second_largest()
except TypeError as e:
if 'root cannot be None' in str(e):
second = None
else:
raise Prevention
- Check tree.root before order-statistic queries
- Populate the tree before querying it
- Wrap the API in an accessor returning None for empty trees
When it happens
Trigger: tree = Bst(); tree.find_second_largest() — calling the method before any insert() has been made, or after all nodes were removed by a future delete operation.
Common situations: Running queries on a freshly constructed tree, on a tree populated conditionally where the data path was empty, or ordering operations incorrectly (query before insert).
Related errors
- data cannot be None
- root must have at least one child
- number cannot be None
- a or b cannot be None
- Invalid argument: None
AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28).
Data as JSON: /api/errors/66f571d33a8a6618.
Report an issue: GitHub.