Bug Report
Description
OmegaConf.resolve() raises RuntimeError: dictionary changed size during iteration on Python 3.12+ when a custom resolver returns a DictConfig (Container).
Root Cause
_resolve() in omegaconf/_impl.py iterates over a live dict_keys view:
for k in cfg.keys():
_resolve_container_value(cfg, k)
Inside _resolve_container_value, when a resolver returns a Container and the current node is a ValueNode, the result is assigned back:
if isinstance(resolved, Container) and isinstance(node, ValueNode):
cfg[key] = resolved
This assignment modifies the underlying dict while the cfg.keys() view is being iterated. Python 3.12+ introduced stricter checks that raise RuntimeError on structural dict modifications during iteration.
Minimal Reproduction
from omegaconf import OmegaConf, ListMergeMode
def merge(*args):
return OmegaConf.merge(*args, list_merge_mode=ListMergeMode.EXTEND)
OmegaConf.register_new_resolver("merge", merge, replace=True)
cfg = OmegaConf.create({
"base": {"x": 1, "y": 2},
"extra": {"z": 3},
"merged": "${merge:${base},${extra}}",
})
OmegaConf.resolve(cfg) # RuntimeError: dictionary changed size during iteration
Traceback
File ".../omegaconf/_impl.py", line 52, in _resolve
for k in cfg.keys():
~~~~~~~~^^
RuntimeError: dictionary changed size during iteration
Environment
- Python 3.12+ (confirmed on 3.12 and 3.14)
- omegaconf 2.4.0.dev4
- Works on Python ≤ 3.11
Fix
Snapshot the keys before iterating:
for k in list(cfg.keys()):
_resolve_container_value(cfg, k)
A PR with this fix and a regression test is attached.
Bug Report
Description
OmegaConf.resolve()raisesRuntimeError: dictionary changed size during iterationon Python 3.12+ when a custom resolver returns aDictConfig(Container).Root Cause
_resolve()inomegaconf/_impl.pyiterates over a livedict_keysview:Inside
_resolve_container_value, when a resolver returns aContainerand the current node is aValueNode, the result is assigned back:This assignment modifies the underlying dict while the
cfg.keys()view is being iterated. Python 3.12+ introduced stricter checks that raiseRuntimeErroron structural dict modifications during iteration.Minimal Reproduction
Traceback
Environment
Fix
Snapshot the keys before iterating:
A PR with this fix and a regression test is attached.