Python "RuntimeError: dictionary changed size during iteration" in CI
By Daniel Zoghalchali·Latchkey
Python detected that a dict (or set) gained or lost entries while a loop was iterating over it. Mutating the container mid-iteration invalidates the iterator, so the interpreter raises rather than skip or repeat keys.
What this error means
A loop fails with "RuntimeError: dictionary changed size during iteration". It can be intermittent if the mutation depends on data order.
python
Traceback (most recent call last):
File "app/cache.py", line 18, in evict
for key in cache:
RuntimeError: dictionary changed size during iteration
Diagnose it: is it the build backend or a missing system library?
Python packaging failures in CI split into build-backend configuration problems and missing system headers. The traceback usually points at the backend even when the real cause is an absent -dev package.
Terminal
python -m pip install --upgrade pip build
python -m build --wheel 2>&1 | tail -40
# a compiler error naming a .h file is a system dependency, not a Python one# e.g. "Python.h: No such file" -> python3-dev# "openssl/ssl.h" -> libssl-dev
Common causes
Adding or deleting keys inside the loop
Calling del d[k] or d[new] = ... while iterating for k in d: changes the size and breaks the live iterator.
A helper mutates the same dict during iteration
A function called inside the loop writes to the dict being iterated, indirectly changing its size.
How to fix it
Iterate over a snapshot
Loop over a copy of the keys so mutating the original is safe.
app/cache.py
for key in list(cache.keys()):
if expired(cache[key]):
del cache[key]
Build a new dict instead of mutating in place
Compute the result as a comprehension and reassign, avoiding mid-loop mutation entirely.
app/cache.py
cache = {k: v for k, v in cache.items() if not expired(v)}
How to prevent it
Never add or remove keys while iterating a dict or set directly.
Iterate over list(d) or list(d.items()) when you must mutate.
Prefer rebuilding the container with a comprehension.
Frequently asked questions
What causes Python "RuntimeError: dictionary changed size during iteration" in CI?
There are 2 common causes: adding or deleting keys inside the loop and a helper mutates the same dict during iteration. Calling del d[k] or d[new] = ...
How do I fix Python "RuntimeError: dictionary changed size during iteration" in CI?
There are 2 fixes depending on which cause you have: iterate over a snapshot and build a new dict instead of mutating in place. Work through them in order, since the first is the most common.
What does Python "RuntimeError: dictionary changed size during iteration" in CI actually mean?
A loop fails with "RuntimeError: dictionary changed size during iteration".
How do I stop Python "RuntimeError: dictionary changed size during iteration" in CI happening again?
Never add or remove keys while iterating a dict or set directly. The prevention section lists 3 changes that keep it from recurring.