open-mmlab/mmdetection · error · TypeError
config must be a filename or Config object, but got
Error message
config must be a filename or Config object, but got {type(config)} What it means
init_detector only accepts a config as a str/Path filename or an already-built mmengine Config object. Passing anything else (dict, None, bytes, PosixPath-like objects not subclassing Path) raises this TypeError. Internally the function calls Config.fromfile on str/Path; dicts are deliberately not accepted because lazy imports and variables in config files require file context in some flows.
Solutions
- If you have a dict, convert it: from mmengine.utils import Config; cfg = Config.fromfile('base.py') then cfg.merge_from_dict(your_dict), or write the dict to a temp .py file and pass its path
- Pass the config file path string directly: init_detector('configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py', 'ckpt.pth')
- Pass an mmengine.config.Config object produced by Config.fromfile(path)
- Check the variable is not None before calling (guard CLI arguments)
Example fix
# before
cfg = dict(model=dict(type='FasterRCNN', ...))
model = init_detector(cfg, 'ckpt.pth') # TypeError
# after
from mmengine.config import Config
cfg = Config.fromfile('configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py')
cfg.merge_from_dict(dict(model=dict(backbone=dict(depth=101))))
model = init_detector(cfg, 'ckpt.pth') Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
from mmengine.config import Config
assert config is not None, 'config path was never set'
if isinstance(config, (str, Path)):
config = Config.fromfile(config)
assert isinstance(config, Config), f'expected str/Path/Config, got {type(config)}' Type guard
from mmengine.config import Config
from typing import Union
import pathlib
def is_valid_detector_config(x) -> bool:
return isinstance(x, (str, pathlib.Path, Config)) Try / catch
try:
model = init_detector(config, ckpt, device)
except TypeError as e:
if 'config must be a filename' in str(e):
raise SystemExit('Pass a config file path or Config.fromfile(...) result, not a dict')
raise Prevention
- Normalize configs to Config objects at system entry points
- Guard CLI args: if not args.config: parser.error('--config required')
- Never hand init_detector a plain dict; write/merge through Config.fromfile
When it happens
Trigger: Calling init_detector(cfg_dict, checkpoint) with a plain dict built in Python; passing None because the config path variable was never set; passing an opened file object or a ConfigDict obtained by other means.
Common situations: Programmatically modifying configs in scripts (users naturally build dicts), passing a pathlib2/other Path substitute, or a variable that is None due to an unset CLI arg.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Automatically set "samples_per_gpu"="imgs_per_gpu"=
- center_offset should be in range [0, 1]
- config is now expected to have a `runner` section, please…
- Either scales or octave_base_scale with scales_per_octave…
- Got "imgs_per_gpu"= and "samples_per_gpu"= …
AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27).
Data as JSON: /api/errors/9551c08547f6e34e.
Report an issue: GitHub.
Appendix: source
Thrown at mmdet/apis/inference.py:55
:obj:`Path`, or the config object.
checkpoint (str, optional): Checkpoint path. If left as None, the model
will not load any weights.
palette (str): Color palette used for visualization. If palette
is stored in checkpoint, use checkpoint's palette first, otherwise
use externally passed palette. Currently, supports 'coco', 'voc',
'citys' and 'random'. Defaults to none.
device (str): The device where the anchors will be put on.
Defaults to cuda:0.
cfg_options (dict, optional): Options to override some settings in
the used config.
Returns:
nn.Module: The constructed detector.
"""
if isinstance(config, (str, Path)):
config = Config.fromfile(config)
elif not isinstance(config, Config):
raise TypeError('config must be a filename or Config object, '
f'but got {type(config)}')
if cfg_options is not None:
config.merge_from_dict(cfg_options)
elif 'init_cfg' in config.model.backbone:
config.model.backbone.init_cfg = None
scope = config.get('default_scope', 'mmdet')
if scope is not None:
init_default_scope(config.get('default_scope', 'mmdet'))
model = MODELS.build(config.model)
model = revert_sync_batchnorm(model)
if checkpoint is None:
warnings.simplefilter('once')
warnings.warn('checkpoint is None, use COCO classes by default.')
model.dataset_meta = {'classes': get_classes('coco')}
else:
checkpoint = load_checkpoint(model, checkpoint, map_location='cpu')View on GitHub (pinned to cfd5d3a985)