open-mmlab/mmdetection · error · TypeError
config must be a filename or Config object, but got {type(co
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.
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)
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: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- LoadImageFromFile is not found in the test pipeline
- Visualization needs the "visualizer" termdefined in the conf
- The type of frame_range must be int or list.
- Scale must be a number or tuple of int, but got {type(scale)
- Unrecognized dataset: {dataset}
AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27).
Data as JSON: /api/errors/9551c08547f6e34e.
Report an issue: GitHub.