Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

RecursionError: maximum recursion depth exceeded in Python

Verified FixPython 3.10+Python NativeSilo: core

Quick Fix / Solution Rapide

Add a verified base termination condition (if n <= 1: return 1), convert deep recursion to an iterative loop with a stack, or fix recursive __getattr__ / @property loops.

Root Cause Analysis

This error occurs when Python detects that the current execution thread has exceeded the maximum call stack depth limit (by default 1000 frames in CPython), raising RecursionError to prevent a segmentation fault from exhausting system C stack memory.

CPython Call Stack and Recursion Limits

Each function call in Python allocates a new stack frame (PyFrameObject) to store local variables and instruction pointers. Because CPython uses the underlying OS C stack for frame execution, infinite recursion would trigger unrecoverable process crashes.

Key Root Causes

  1. Missing or Faulty Base Case: A recursive mathematical or tree-traversal function lacking a valid termination check.
  2. Recursive Property / Magic Method Loops: Defining @property def value(self): return self.value (accessing the property instead of self._value).
  3. Circular __getattr__ or __repr__: Accessing an undefined attribute inside __getattr__ without using super().__getattribute__() or self.__dict__.
  4. Deep Graph / Tree Traversals: Traversing deeply nested JSON trees or graphs containing cyclic references.

Reproduction Code (MCVE)

Example: Bug Reproduction
# Simulates infinite recursive function call exceeding call stack limit
def infinite_recurse(depth: int = 0):
    return infinite_recurse(depth + 1)

infinite_recurse()

Solution 1: Add a Strict Base Condition to Recursion

Guarantee that the recursion base case is reached for all possible inputs (including edge cases like 0 and negative numbers).

Example: Recommended Solution
def factorial(n: int) -> int:
    # Strict base case prevents infinite recursion
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(f'Factorial of 5: {factorial(5)}')
print(f'Factorial of 0: {factorial(0)}')

Solution 2: Refactor Deep Recursion to Iterative Stack Loop

Replace recursive function frames with a Python list used as an explicit stack in a while loop, eliminating stack depth limits.

Example: Alternative Solution
def traverse_tree_iterative(root_node: dict) -> list:
    visited = []
    stack = [root_node]
    
    while stack:
        current = stack.pop()
        visited.append(current['id'])
        for child in current.get('children', []):
            stack.append(child)
            
    return visited

tree = {'id': 1, 'children': [{'id': 2, 'children': []}, {'id': 3, 'children': []}]}
print(f'Iterative traversal completed: {traverse_tree_iterative(tree)}')

Common Pitfalls & Dangerous Workarounds

A dangerous antipattern is calling sys.setrecursionlimit(100000). Increasing the recursion limit does not solve infinite recursion bugs; it merely delays the crash until CPython causes a hard segmentation fault (SIGSEGV) that kills the Python process without an exception traceback. Always refactor to an iterative algorithm.

Contrasting with related errors:

  • RecursionError: Exceeded frame depth stack.
  • MemoryError: Out of RAM when allocating large arrays/objects.
  • TimeoutError: Asynchronous coroutine did not finish in time.