Fix Python RecursionError: maximum recursion depth exceeded

intermediate🐍 Python2026-03-18| Python 3.x on Linux, macOS, Windows

Error Message

RecursionError: maximum recursion depth exceeded
#python#recursion#sys

What triggers this error

Python caps the call stack at 1000 frames by default. When a function calls itself β€” directly or through a chain β€” and nothing stops it before that cap, you get:

RecursionError: maximum recursion depth exceeded

Four situations cause this almost every time:

  • A recursive function with no base case at all
  • A base case that exists but is never reached due to a logic bug
  • Deeply nested data β€” JSON trees, XML documents, AST nodes with hundreds of levels
  • Accidentally overriding a built-in like __eq__ or __repr__ so it calls itself

Reading the traceback

The traceback makes the culprit obvious. The same two or three lines repeat hundreds of times:

File "app.py", line 5, in factorial
  return n * factorial(n - 1)
File "app.py", line 5, in factorial
  return n * factorial(n - 1)
  [Previous line repeated 996 more times]

That repeating line is your problem. The fix depends on why it keeps looping.

Fix 1 β€” Add or correct the base case

Nine times out of ten, this is the actual problem. Every recursive function needs a condition that stops the chain.

Broken:

def factorial(n):
    return n * factorial(n - 1)  # never stops

Fixed:

def factorial(n):
    if n n) to O(n).

## Fix 5 β€” Catch accidental self-calls in __repr__ and __eq__
Easy to miss: define `__repr__` and use `f"{self}"` inside it. That format string triggers `__repr__` again. Infinite loop.

BAD β€” infinite recursion

class Node: def repr(self): return f"Node({self})" # calls repr on self!

GOOD β€” reference the value, not self

class Node: def init(self, val): self.val = val def repr(self): return f"Node({self.val})"


The same trap exists in `__eq__` and `__hash__`. If either one implicitly calls the other, you'll see the same spiral.

## Verify the fix
Run your function against edge cases β€” zero, negative inputs, and whatever size was crashing before:

import sys print(sys.getrecursionlimit()) # confirm current limit

result = factorial(999) print(result) # large number, no RecursionError

If you raised the limit, probe near the new boundary

sys.setrecursionlimit(3000) result = factorial(2500) print("OK")


No exception across your full input range means the fix held.

## Quick reference

  - **Missing base case** β†’ add the termination condition
  - **Correct logic, deep input** β†’ `sys.setrecursionlimit(N)`
  - **Production/large data** β†’ rewrite with a loop + explicit stack
  - **Repeated subproblems** β†’ add `@lru_cache`
  - **Accidental self-call** β†’ check `__repr__`, `__eq__`, `__hash__`

Related Error Notes