Skip to content
Latchkey

Python "RuntimeError: dictionary changed size during iteration" in CI

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

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.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →