open-mmlab/mmdetection · error · TypeError

pretrained must be a str or None

Error message

pretrained must be a str or None

What it means

HRNet's legacy init path accepts pretrained only as a str path/URL or None; anything else (dict, list) raises TypeError('pretrained must be a str or None'). Like other mmdet backbones, HRNet has migrated to init_cfg-based weight loading.

Source

Thrown at mmdet/models/backbones/hrnet.py:311

        self.pretrained = pretrained
        assert not (init_cfg and pretrained), \
            'init_cfg and pretrained cannot be specified at the same time'
        if isinstance(pretrained, str):
            warnings.warn('DeprecationWarning: pretrained is deprecated, '
                          'please use "init_cfg" instead')
            self.init_cfg = dict(type='Pretrained', checkpoint=pretrained)
        elif pretrained is None:
            if init_cfg is None:
                self.init_cfg = [
                    dict(type='Kaiming', layer='Conv2d'),
                    dict(
                        type='Constant',
                        val=1,
                        layer=['_BatchNorm', 'GroupNorm'])
                ]
        else:
            raise TypeError('pretrained must be a str or None')

        # Assert configurations of 4 stages are in extra
        assert 'stage1' in extra and 'stage2' in extra \
               and 'stage3' in extra and 'stage4' in extra
        # Assert whether the length of `num_blocks` and `num_channels` are
        # equal to `num_branches`
        for i in range(4):
            cfg = extra[f'stage{i + 1}']
            assert len(cfg['num_blocks']) == cfg['num_branches'] and \
                   len(cfg['num_channels']) == cfg['num_branches']

        self.extra = extra
        self.conv_cfg = conv_cfg
        self.norm_cfg = norm_cfg
        self.norm_eval = norm_eval
        self.with_cp = with_cp
        self.zero_init_residual = zero_init_residual

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Use init_cfg=dict(type='Pretrained', checkpoint='open-mmlab://hrnetv2_w32') instead of pretrained
  2. If pretrained is kept, pass a plain string or None
  3. Remove stale pretrained keys when inheriting old base configs (use _delete_=True on the backbone dict)

Example fix

# before
backbone=dict(type='HRNet', pretrained='open-mmlab://hrnetv2_w32', extra=...)
# after
backbone=dict(type='HRNet', init_cfg=dict(type='Pretrained', checkpoint='open-mmlab://hrnetv2_w32'), extra=...)
Defensive patterns

Strategy: type-guard

Validate before calling

assert pretrained is None or isinstance(pretrained, str), 'HRNet pretrained must be str or None'

Type guard

def is_valid_pretrained(p) -> bool:
    return p is None or isinstance(p, str)

Prevention

When it happens

Trigger: Passing pretrained=dict(checkpoint='...') to HRNet; passing a non-str object while also relying on the deprecated init_weights branch.

Common situations: Migrating MMDetection 1.x configs; mixing pretrained and init_cfg; script-generated configs embedding dicts.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/f74974dfa68d00dd. Report an issue: GitHub.