donnemartin/interactive-coding-challenges · error · TypeError
root cannot be None
Error message
root cannot be None
What it means
BinaryTreeOptimized.lca raises TypeError('root cannot be None') when the root argument is None; the algorithm needs a non-empty tree to compute the lowest common ancestor. This differs from sibling implementations that return None, so read the signature carefully: root is a parameter here, not an attribute.
Source
Thrown at graphs_trees/tree_lca/tree_lca_solution.ipynb:168
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"class LcaResult(object):\n",
"\n",
" def __init__(self, node, is_ancestor):\n",
" self.node = node\n",
" self.is_ancestor = is_ancestor\n",
"\n",
"\n",
"class BinaryTreeOptimized(object):\n",
"\n",
" def lca(self, root, node1, node2):\n",
" if root is None:\n",
" raise TypeError('root cannot be None')\n",
" result = self._lca(root, node1, node2)\n",
" if result.is_ancestor:\n",
" return result.node\n",
" return None\n",
"\n",
" def _lca(self, curr_node, node1, node2):\n",
" if curr_node is None:\n",
" return LcaResult(None, is_ancestor=False)\n",
" if curr_node is node1 and curr_node is node2:\n",
" return LcaResult(curr_node, is_ancestor=True)\n",
" left_result = self._lca(curr_node.left, node1, node2)\n",
" if left_result.is_ancestor:\n",
" return left_result\n",
" right_result = self._lca(curr_node.right, node1, node2)\n",
" if right_result.is_ancestor:\n",
" return right_result\n",
" if left_result.node is not None and right_result.node is not None:\n",
" return LcaResult(curr_node, is_ancestor=True)\n",View on GitHub (pinned to 358f2cc604)
Solutions
- Ensure root is a real Node before calling lca (build the tree from non-empty data)
- Guard: if root is not None: result = tree.lca(root, n1, n2)
- Catch TypeError in tests covering the empty-tree edge case
Example fix
// before
result = solution.lca(tree_root, node1, node2) # TypeError if tree_root is None
// after
if tree_root is not None:
result = solution.lca(tree_root, node1, node2)
else:
result = None Defensive patterns
Strategy: type-guard
Validate before calling
if root is None:
return None
return solution.lca(root, node1, node2) Type guard
def is_node(x) -> bool:
return x is not None and hasattr(x, 'left') and hasattr(x, 'right') Try / catch
try:
return solution.lca(root, node1, node2)
except TypeError:
return None # empty tree has no LCA Prevention
- Never assume this implementation tolerates None roots like sibling versions
- Validate tree-builder output before passing roots to LCA
When it happens
Trigger: Calling lca(None, node1, node2), or passing a tree's root that was never assigned (empty tree built from empty input).
Common situations: Constructing test trees via a helper that returns None for empty arrays, or switching from another LCA implementation in this repo that silently handles None roots, creating mismatched expectations.
Related errors
- root is None
- data cannot be None
- root cannot be None
- root must have at least one child
- root cannot be None
AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28).
Data as JSON: /api/errors/af7b1b503aec7506.
Report an issue: GitHub.