open-mmlab/mmdetection · warning · UserWarning
config is now expected to have a `runner` section, please se
Error message
config is now expected to have a `runner` section, please set `runner` in your config.
What it means
compat_runner_args in mmdet/utils/compat_config.py fires when a config lacks a runner section but still carries the MMDet V1.x-style total_epochs key. It auto-creates cfg.runner = {'type': 'EpochBasedRunner', 'max_epochs': total_epochs} so training proceeds, then warns that configs are expected to declare runner explicitly in V2.x style.
Source
Thrown at mmdet/utils/compat_config.py:28
config.
For example, it will move some args which will be deprecated to the correct
fields.
"""
cfg = copy.deepcopy(cfg)
cfg = compat_imgs_per_gpu(cfg)
cfg = compat_loader_args(cfg)
cfg = compat_runner_args(cfg)
return cfg
def compat_runner_args(cfg):
if 'runner' not in cfg:
cfg.runner = ConfigDict({
'type': 'EpochBasedRunner',
'max_epochs': cfg.total_epochs
})
warnings.warn(
'config is now expected to have a `runner` section, '
'please set `runner` in your config.', UserWarning)
else:
if 'total_epochs' in cfg:
assert cfg.total_epochs == cfg.runner.max_epochs
return cfg
def compat_imgs_per_gpu(cfg):
cfg = copy.deepcopy(cfg)
if 'imgs_per_gpu' in cfg.data:
warnings.warn('"imgs_per_gpu" is deprecated in MMDet V2.0. '
'Please use "samples_per_gpu" instead')
if 'samples_per_gpu' in cfg.data:
warnings.warn(
f'Got "imgs_per_gpu"={cfg.data.imgs_per_gpu} and '
f'"samples_per_gpu"={cfg.data.samples_per_gpu}, "imgs_per_gpu"'
f'={cfg.data.imgs_per_gpu} is used in this experiments')View on GitHub (pinned to cfd5d3a985)
Solutions
- Replace total_epochs = 12 in your config with runner = dict(type='EpochBasedRunner', max_epochs=12).
- If you must keep total_epochs for compat, also set runner with a matching max_epochs so the assert passes.
- For IterBasedRunner-style training use runner = dict(type='IterBasedRunner', max_iters=...) and keep total_epochs out of the config.
- Re-run compat_cfg() after edits to confirm the warning disappears.
Example fix
# before total_epochs = 12 # after runner = dict(type='EpochBasedRunner', max_epochs=12)
Defensive patterns
Strategy: validation
Validate before calling
from mmcv import Config
def check_runner(cfg: Config) -> Config:
if 'runner' not in cfg:
cfg.runner = dict(type='EpochBasedRunner', max_epochs=cfg.get('total_epochs', 12))
cfg.pop('total_epochs', None)
return cfg Prevention
- Always author configs with an explicit runner section in mmdet 2.x.
- Lint configs with a startup check that asserts 'runner' in cfg before training.
- Never mix total_epochs and runner.max_epochs with mismatched values (the code asserts).
When it happens
Trigger: Running a training entrypoint (tools/train.py) or any code path that calls compat_cfg(cfg) with a config that defines total_epochs=N but no runner=dict(...) block. The assert branch fires instead if both exist and disagree: assert cfg.total_epochs == cfg.runner.max_epochs.
Common situations: Porting old MMDet V1.x configs or community configs to V2.x; upgrading mmdetection versions where runner was introduced; copy-pasting a legacy config into a newer install.
Related errors
- "imgs_per_gpu" is deprecated in MMDet V2.0. Please use "samp
- Automatically set "samples_per_gpu"="imgs_per_gpu"={cfg.data
- The `file_client_args` is deprecated, please use `backend_ar
- The `file_client_args` is deprecated, please use `backend_ar
- The `file_client_args` is deprecated, please use `backend_ar
AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27).
Data as JSON: /api/errors/e52f8c69d2349698.
Report an issue: GitHub.