How to Fix: StopIteration Error in Python

3D illustration of an empty gumball machine flagging an error when the crank is turned, representing StopIteration.

This “error” is actually a normal part of Python’s machinery, and in this case refers to the StopIteration Error. It’s not a bug; it’s a signal.

StopIteration is the exception that gets raised when an iterator (like a generator or file object) has no more items to give.

The Cause

You almost never see this in a for loop, because the for loop is designed to automatically catch this signal and stop.

You only see StopIteration when you are manually using the next() function.

โšก Quick Fix: StopIteration Error in Python โ€” next() Default Value Fix and Generator Function Handling for Exhausted Iterators

Python raised StopIteration because you called next() on an iterator that already delivered its last item โ€” the well is empty and you asked for one more.

# WRONG โ€” calling next() past the last item crashes immediately
my_list = [1, 2]
my_iterator = iter(my_list)

print(next(my_iterator))   # Output: 1
print(next(my_iterator))   # Output: 2
print(next(my_iterator))   # StopIteration โ€” no items left

# FIX 1 โ€” pass a default value to next(): returns the default instead of crashing
print(next(my_iterator, None))    # Output: None โ€” no crash
print(next(my_iterator, "done"))  # Output: done โ€” no crash

# FIX 2 โ€” use a for loop: handles StopIteration automatically, always
for item in my_list:
    print(item)             # Python catches StopIteration internally, stops cleanly

# FIX 3 โ€” generators: wrap next() in try/except when you must use manual iteration
def number_generator():
    yield 1
    yield 2

gen = number_generator()
try:
    while True:
        print(next(gen))
except StopIteration:
    print("Generator exhausted.")

The breakdown below explains when StopIteration is a crash versus a normal signal โ€” and the PEP 479 change that turns it into a RuntimeError inside generators.

Problem Code:

my_list = [1, 2]
my_iterator = iter(my_list) # Get an iterator for the list

print(next(my_iterator)) # Output: 1
print(next(my_iterator)) # Output: 2
print(next(my_iterator)) # CRASH! StopIteration

The program crashes because you asked for a third item, but the list was empty.

The Fix: Use try/except (If you must use next())

If you’re manually calling next(), you must also manually catch the StopIteration.

my_list = [1, 2]
my_iterator = iter(my_list)

try:
    while True:
        item = next(my_iterator)
        print(item)
except StopIteration:
    print("All items have been processed.")

The Real Fix: Use a for loop

The for loop does all of this for you. It’s cleaner, safer, and what you should use 99% of the time.

# This is the correct, Pythonic way
my_list = [1, 2]
for item in my_list:
    print(item)

StopIteration Error in Python โ€” next(), Generators, and the PEP 479 Rule Every Developer Needs

StopIteration is not a defect in your code. It is the signal every Python iterator sends when it runs out of items. The for loop catches it silently. next() surfaces it as a visible exception.

Two fixes cover every real-world scenario.

Pass a default value to next(). next(iterator, None) returns None when the iterator is exhausted instead of raising StopIteration. next(iterator, “DONE”) returns “DONE”. This single argument eliminates the crash in every case where you call next() in a loop or conditional and expect the iterator might be empty.

Use a for loop. for item in my_iterator: is the correct tool for sequential processing of any iterable โ€” lists, generators, file objects, database cursors. Python’s for loop calls next() internally, catches StopIteration automatically, and stops cleanly. Manual next() belongs only in code where you need fine-grained control over iteration pace: parsers, coroutines, and custom protocol implementations.

The PEP 479 rule matters for generator authors. Before Python 3.7, a StopIteration raised inside a generator function propagated silently out of the generator. Since Python 3.7, it converts to RuntimeError: generator raised StopIteration. If you write generator functions and call next() inside them, wrap that call in try/except StopIteration โ€” never let it propagate naturally inside a yield-based function.

def safe_first(iterable):
try:
return next(iter(iterable))
except StopIteration:
return None # empty iterable โ€” return a safe default

safe_first([]) # returns None, no crash
safe_first([1, 2, 3]) # returns 1

Similar Posts

Leave a Reply