Debugging — Python Error Guide

RecursionError —
The call stack ran out of room.

A recursive function called itself past Python's ~1000-frame limit without ever reaching a base case. It's almost always a missing or unreachable base case, not a "the recursion is too deep for a good reason" problem. Watch the call stack climb frame by frame on LearnBug and see the exact point it gives up.

RecursionErrorException type
~1000Default call depth limit
PythonLanguage

What is RecursionError?

Python raises RecursionError: maximum recursion depth exceeded when a chain of function calls nests deeper than the interpreter's configured limit (about 1000 by default). It's Python's safety net against a call stack that would otherwise grow forever and crash the whole process.

Why visualization helps

By the time you see the traceback, the interesting part — exactly which call should have stopped the recursion, and why it didn't — has already scrolled past. LearnBug lets you watch the stack climb one frame at a time and see the base case check either fire correctly or silently get skipped.

LearnBug — the call stack climbing toward the limit
🖼 Add a LearnBug screenshot here
What Causes It

Three ways a recursive function loses its base case

No base case at all

The function has no condition that returns without recursing — every call, no matter the input, calls itself again.

Missing check

Base case exists but is unreachable

A recursive call forgets to move the input closer to the base case (e.g. calling with the same value instead of n-1), so the base case condition never becomes true.

No progress

Genuine deep recursion, no bug at all

Sometimes the recursion is correct but the input is simply too large for the default limit — processing a deeply nested structure, for example.

Input too large
Walkthrough

countdown(5) with no base case

1

countdown(5) prints 5, calls countdown(4) — looks completely normal

Each call prints its value and immediately calls itself with one less. For the first several calls, this is indistinguishable from correctly-written recursion.

5
4
3
Stack depth: 3  |  Nothing looks wrong yet
2

n reaches 0, then goes negative — no check ever catches it

There's no if n == 0: return anywhere in this function. n sails straight through the value that should have stopped it and keeps decreasing forever.

0should stop!
-1
-2
n keeps decreasing past 0 — no base case exists to catch it
3

Stack depth climbs past 900, 950, 999 — every frame identical

There's nothing different about frame 500 vs frame 999 — they're all waiting on the exact same kind of call, with no end condition anywhere in sight.

-996
-997
-998
Stack depth: ~998  |  Approaching Python's ~1000 frame limit
4

Frame ~1000: Python refuses to push another — RecursionError

Python doesn't know the recursion will never stop — it just enforces its configured depth limit and raises the error once that limit is crossed, unwinding every pending frame as the exception propagates back up.

Result: RecursionError: maximum recursion depth exceeded

Code Example

The broken code, and the traceback it produces

PythonBroken — no base case
def countdown(n):
    print(n)
    return countdown(n - 1)   # no base case — n never stops decreasing

countdown(5)
TracebackWhat Python actually prints
Traceback (most recent call last):
  File "countdown.py", line 3, in countdown
    return countdown(n - 1)
  File "countdown.py", line 3, in countdown
    return countdown(n - 1)
  File "countdown.py", line 3, in countdown
    return countdown(n - 1)
  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
The Fix

Add a base case that's actually reachable

PythonFixed — base case stops the recursion
def countdown(n):
    if n == 0:            # base case — this is what makes it stop
        return
    print(n)
    return countdown(n - 1)

countdown(5)   # 5, 4, 3, 2, 1

Quick Reference

Error classRecursionErrorRaised when call-stack depth exceeds Python's configured recursion limit
Typical causeMissing/unreachable base caseAlmost always a logic bug, not an intentional deep recursion
Fix patternAdd or fix the base caseEnsure a condition returns without recursing, and every call moves toward it
If it's genuinely neededRewrite iterativelyDon't just raise sys.setrecursionlimit() — convert to a loop or explicit stack instead

Frequently asked questions

Should I just call sys.setrecursionlimit() to fix this?

Almost never. Raising the limit doesn't fix a genuinely broken base case — it just delays the crash, and risks a real OS-level stack overflow that can crash the Python interpreter itself instead of raising a catchable exception. Fix the base case, or convert to an iterative version if the recursion is intentionally deep.

How do I tell if my recursion is a bug or just legitimately deep?

Check whether the recursion depth scales with something bounded and small (a fixed algorithm like factorial(5)) or something that could genuinely be large (traversing a deeply nested JSON structure from untrusted input, for example). If it's the latter, an iterative rewrite with an explicit stack is the safer long-term fix.

Why does the traceback say "Previous line repeated 996 more times"?

Python detects that the same call is repeating identically and collapses the repeated traceback lines instead of printing all ~1000 of them — a readability feature, not a different kind of error. The full call chain is still exactly as long; only the printed output is compressed.

Does every programming language have this same limit?

Most do, though the exact mechanism and default depth vary — some languages support tail-call optimization, which can eliminate the stack growth entirely for certain recursive patterns. Python deliberately does not implement tail-call optimization, so even a "tail-recursive" Python function still consumes stack depth per call.

Watch your own recursion hit the limit — or not

Paste your recursive function into LearnBug and see the call stack build frame by frame.

Open Playground →