open-mmlab/mmdetection · error · TypeError

pretrained must be a str or None

Error message

pretrained must be a str or None

What it means

DetectoRS_ResNet.init_weights (legacy pretrained path) raises TypeError('pretrained must be a str or None') when self.pretrained is neither a string nor None, e.g. left as a dict from a misconfigured init_cfg or positional arg. It occurs at weight-initialization time, not construction.

Source

Thrown at mmdet/models/backbones/detectors_resnet.py:323

                if isinstance(m, nn.Conv2d):
                    kaiming_init(m)
                elif isinstance(m, (_BatchNorm, nn.GroupNorm)):
                    constant_init(m, 1)

            if self.dcn is not None:
                for m in self.modules():
                    if isinstance(m, Bottleneck) and hasattr(
                            m.conv2, 'conv_offset'):
                        constant_init(m.conv2.conv_offset, 0)

            if self.zero_init_residual:
                for m in self.modules():
                    if isinstance(m, Bottleneck):
                        constant_init(m.norm3, 0)
                    elif isinstance(m, BasicBlock):
                        constant_init(m.norm2, 0)
        else:
            raise TypeError('pretrained must be a str or None')

    def make_res_layer(self, **kwargs):
        """Pack all blocks in a stage into a ``ResLayer`` for DetectoRS."""
        return ResLayer(**kwargs)

    def forward(self, x):
        """Forward function."""
        outs = list(super(DetectoRS_ResNet, self).forward(x))
        if self.output_img:
            outs.insert(0, x)
        return tuple(outs)

    def rfp_forward(self, x, rfp_feats):
        """Forward function for RFP."""
        if self.deep_stem:
            x = self.stem(x)
        else:
            x = self.conv1(x)

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Remove the legacy pretrained argument; set weights via init_cfg=dict(type='Pretrained', checkpoint='...')
  2. If pretrained must be used, pass a plain string path or None
  3. Audit config inheritance (_delete_=True where needed) so stale pretrained keys do not leak

Example fix

# before
model = dict(backbone=dict(type='DetectoRS_ResNet', pretrained=dict(checkpoint='torchvision://resnet50')))
# after
model = dict(backbone=dict(type='DetectoRS_ResNet', init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')))
Defensive patterns

Strategy: type-guard

Validate before calling

assert model.backbone.pretrained is None or isinstance(model.backbone.pretrained, str)

Type guard

def clean_pretrained(p):
    if p is None or isinstance(p, str):
        return p
    if isinstance(p, dict) and 'checkpoint' in p:
        return p['checkpoint']
    raise TypeError('pretrained must be a str or None')

Try / catch

try:
    model.backbone.init_weights()
except TypeError as e:
    if 'pretrained' in str(e):
        model.backbone.pretrained = None; model.backbone.init_weights()
    else: raise

Prevention

When it happens

Trigger: Constructing DetectoRS_ResNet with pretrained=dict(...) or a non-str value; init_cfg mishandling that leaves self.pretrained set to a dict; then calling model.init_weights() or runner init.

Common situations: Configs migrating from MMDetection 1.x style pretrained=dict(type='Pretrained', checkpoint=...) passed via the wrong argument; merging configs that leave a stale pretrained value.

Related errors


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