donnemartin/interactive-coding-challenges · error · TypeError
node cannot be None
Error message
node cannot be None
What it means
BstSuccessor.get_next raises TypeError('node cannot be None') when the node argument is None. The routine immediately dereferences node.right to find the in-order successor, so a None node is rejected before that access.
Source
Thrown at graphs_trees/bst_successor/bst_successor_solution.ipynb:114
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%run ../bst/bst.py"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"class BstSuccessor(object):\n",
"\n",
" def get_next(self, node):\n",
" if node is None:\n",
" raise TypeError('node cannot be None')\n",
" if node.right is not None:\n",
" return self._left_most(node.right)\n",
" else:\n",
" return self._next_ancestor(node)\n",
"\n",
" def _left_most(self, node):\n",
" if node.left is not None:\n",
" return self._left_most(node.left)\n",
" else:\n",
" return node.data\n",
"\n",
" def _next_ancestor(self, node):\n",
" if node.parent is not None:\n",
" if node.parent.data > node.data:\n",
" return node.parent.data\n",
" else:\n",
" return self._next_ancestor(node.parent)\n",
" # We reached the root, the original input node\n",View on GitHub (pinned to 358f2cc604)
Solutions
- Check for None between chained get_next calls and stop the loop
- Guard the argument: if node is None: break/return before calling
- Use the return value's None-ness as the end-of-traversal signal
Example fix
# before
node = root
while True:
node = succ.get_next(node) # crashes when node is None
# after
node = root
while node is not None:
process(node)
node = succ.get_next(node) if node is not root else succ.get_next(node)
# simpler: check before each call
node = succ.get_next(root)
while node is not None:
process(node)
node = succ.get_next(node) Defensive patterns
Strategy: type-guard
Validate before calling
if node is None:
return None # end of traversal
successor.get_next(node) Type guard
def is_node(n) -> bool:
return n is not None Try / catch
try:
nxt = succ.get_next(node)
except TypeError as e:
if 'cannot be None' in str(e):
nxt = None # treat as end of tree
else:
raise Prevention
- Always loop with 'while node is not None' in successor traversals
- Treat a None successor result as the termination signal
- Never chain get_next() without an intermediate None check
When it happens
Trigger: succ.get_next(None), or get_next(succ.get_next(current)) when current was the last node in the tree and get_next returned None, chaining calls in a traversal loop.
Common situations: Iterating a BST via successor calls without a termination check; traversals that assume another node exists past the maximum element.
Related errors
- data cannot be None
- number cannot be None
- a or b cannot be None
- Invalid argument: None
- num cannot be None
AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28).
Data as JSON: /api/errors/abea0977e4f57f47.
Report an issue: GitHub.