{"record":{"id":"0e07474215ec57d9","repo":"open-mmlab/mmdetection","slug":"module-must-be-a-str-or-a-list","errorCode":null,"errorMessage":"module must be a str or a list.","messagePattern":"module must be a str or a list\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"mmdet/models/mot/base.py","lineNumber":36,"sourceCode":"        data_preprocessor (dict or ConfigDict, optional): The pre-process\n           config of :class:`TrackDataPreprocessor`.  it usually includes,\n            ``pad_size_divisor``, ``pad_value``, ``mean`` and ``std``.\n        init_cfg (dict or list[dict]): Initialization config dict.\n    \"\"\"\n\n    def __init__(self,\n                 data_preprocessor: OptConfigType = None,\n                 init_cfg: OptMultiConfig = None) -> None:\n        super().__init__(\n            data_preprocessor=data_preprocessor, init_cfg=init_cfg)\n\n    def freeze_module(self, module: Union[List[str], Tuple[str], str]) -> None:\n        \"\"\"Freeze module during training.\"\"\"\n        if isinstance(module, str):\n            modules = [module]\n        else:\n            if not (isinstance(module, list) or isinstance(module, tuple)):\n                raise TypeError('module must be a str or a list.')\n            else:\n                modules = module\n        for module in modules:\n            m = getattr(self, module)\n            m.eval()\n            for param in m.parameters():\n                param.requires_grad = False\n\n    @property\n    def with_detector(self) -> bool:\n        \"\"\"bool: whether the framework has a detector.\"\"\"\n        return hasattr(self, 'detector') and self.detector is not None\n\n    @property\n    def with_reid(self) -> bool:\n        \"\"\"bool: whether the framework has a reid model.\"\"\"\n        return hasattr(self, 'reid') and self.reid is not None\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/open-mmlab/mmdetection/blob/cfd5d3a985b0249de009b67d04f37263e11cdf3d/mmdet/models/mot/base.py#L18-L54","documentation":"Raised by BaseMot.freeze_module when the `module` argument passed to freeze_module (or the `freeze_module` config field of a MOT model) is neither a str, list, nor tuple. The method resolves each entry with getattr(self, name) to set that submodule to eval mode and freeze its parameters, so the argument type must be one of the three supported container types.","triggerScenarios":"Setting `freeze_module=3` or a dict/None in a MOT (e.g. QDTrack/ByteTrack) config, or calling model.freeze_module({'detector'}) / freeze_module(None) directly.","commonSituations":"Copy-paste of a config where freeze_module was deleted leaving a wrong-typed value; YAML parsing a scalar that was meant to be a quoted attribute name; passing a detector module object instead of its attribute name string.","solutions":["Set freeze_module to an attribute name string, e.g. freeze_module = 'detector', or a list of names, e.g. freeze_module = ['detector', 'reid']","If you do not want to freeze anything, remove the freeze_module field from the config","When calling programmatically, pass module names (str) matching nn.Module attributes of self"],"exampleFix":"# before\nfreeze_module = 2  # or {'detector'}\n# after\nfreeze_module = ['detector']","handlingStrategy":"type-guard","validationCode":"from typing import List, Tuple, Union\nok = isinstance(freeze, (str, list, tuple)) and all(isinstance(m, str) for m in (freeze if isinstance(freeze,(list,tuple)) else [freeze]))","typeGuard":"def is_valid_freeze_spec(v) -> bool:\n    if isinstance(v, str): return True\n    return isinstance(v, (list, tuple)) and len(v) > 0 and all(isinstance(x, str) for x in v)","tryCatchPattern":null,"preventionTips":["Validate config freeze_module is a str or list[str] before building the model","Use cfg sanity-check tools or print(cfg.freeze_module) when editing configs"],"tags":["mmdetection","mot","config","type-error"],"backgroundTag":"invalid-config-value","analyzedSha":"cfd5d3a985b0249de009b67d04f37263e11cdf3d","analyzedAt":"2026-08-27T20:54:20.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}