RecursionError: maximum recursion depth exceeded

Python · updated 2026-11-03

Raised when the call stack passes sys.getrecursionlimit(), 1000 by default. The traceback shows the same few lines repeating, often collapsed as "[Previous line repeated 996 more times]"; those lines are the recursion to fix.

Traceback (most recent call last):
  File "/app/tree.py", line 30, in <module>
    print(depth(root))
  File "/app/tree.py", line 6, in depth
    return 1 + max(depth(c) for c in node.children)
  File "/app/tree.py", line 6, in <genexpr>
    return 1 + max(depth(c) for c in node.children)
  File "/app/tree.py", line 6, in depth
    return 1 + max(depth(c) for c in node.children)
  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

Quick fix

Read the repeating frames: they name the function. If it never stops, fix the base case or the data (a cycle in a graph, an object that references itself). If the data is legitimately deep, rewrite the recursion as a loop with an explicit stack instead of raising the limit.

  1. Find the function in the repeated frames of the traceback.
  2. Check the base case: does every call move toward it?
  3. For graphs or self-referencing objects, track visited ids so a cycle stops the walk.
  4. For deep but finite data, convert to an iterative loop with a list as the stack.
  5. Raise sys.setrecursionlimit only as a last resort and with a modest value.
python
def depth(root) -> int:
    """Iterative version: no recursion limit, handles cycles."""
    best, stack, seen = 0, [(root, 1)], set()
    while stack:
        node, d = stack.pop()
        if id(node) in seen:
            continue            # cycle: already visited
        seen.add(id(node))
        best = max(best, d)
        stack.extend((c, d + 1) for c in node.children)
    return best

Why it happens

A missing or unreachable base case

A condition that never becomes true (an off-by-one, comparing the wrong field, mutating the wrong variable) makes the function call itself until Python stops it.

A cycle in the data

Walking a graph, a parent and child pair that point at each other, or an ORM object with back-references revisits the same nodes forever without a visited set.

A property or __getattr__ that calls itself

A property that reads self.value inside its own getter, or __getattr__ that touches an attribute that is not set yet, recurses on every access.

Legitimately deep input

Deeply nested JSON, long linked lists or recursive parsers over big inputs can pass 1000 frames even when the code is correct.

Other fixes

  • In properties, store the value in a differently named attribute (self._value) to avoid calling the property from itself.
  • For JSON that might be deeply nested from untrusted sources, cap nesting depth before parsing it recursively.
  • functools.lru_cache does not prevent the error: memoization helps repeated calls, not depth.

Same error, other wording

  • RecursionError: maximum recursion depth exceeded while calling a Python object
  • RecursionError: maximum recursion depth exceeded in comparison
  • RecursionError: maximum recursion depth exceeded while getting the str of an object

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the RecursionError events in production, show me the function that repeats in each traceback and the input that triggered it, and make it iterative or fix the stop condition.

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: Python docs: RecursionError, Python docs: sys.setrecursionlimit