{"record":{"id":"bad2104ea5438b5c","repo":"open-mmlab/mmdetection","slug":"visualization-needs-the-visualizer-termdefined-i","errorCode":null,"errorMessage":"Visualization needs the \"visualizer\" termdefined in the config, but got None.","messagePattern":"Visualization needs the \"visualizer\" termdefined in the config, but got None\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mmdet/apis/det_inferencer.py","lineNumber":469,"sourceCode":"            pred_score_thr (float): Minimum score of bboxes to draw.\n                Defaults to 0.3.\n            no_save_vis (bool): Whether to force not to save prediction\n                vis results. Defaults to False.\n            img_out_dir (str): Output directory of visualization results.\n                If left as empty, no file will be saved. Defaults to ''.\n\n        Returns:\n            List[np.ndarray] or None: Returns visualization results only if\n            applicable.\n        \"\"\"\n        if no_save_vis is True:\n            img_out_dir = ''\n\n        if not show and img_out_dir == '' and not return_vis:\n            return None\n\n        if self.visualizer is None:\n            raise ValueError('Visualization needs the \"visualizer\" term'\n                             'defined in the config, but got None.')\n\n        results = []\n\n        for single_input, pred in zip(inputs, preds):\n            if isinstance(single_input, str):\n                img_bytes = mmengine.fileio.get(single_input)\n                img = mmcv.imfrombytes(img_bytes)\n                img = img[:, :, ::-1]\n                img_name = osp.basename(single_input)\n            elif isinstance(single_input, np.ndarray):\n                img = single_input.copy()\n                img_num = str(self.num_visualized_imgs).zfill(8)\n                img_name = f'{img_num}.jpg'\n            else:\n                raise ValueError('Unsupported input type: '\n                                 f'{type(single_input)}')\n","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/open-mmlab/mmdetection/blob/cfd5d3a985b0249de009b67d04f37263e11cdf3d/mmdet/apis/det_inferencer.py#L451-L487","documentation":"DetInferencer.visualize() raises this when visualization is requested (show=True, img_out_dir set, or return_vis=True) but self.visualizer is None. The visualizer is only constructed when the config defines a 'visualizer' term (via default_scope/hooks init or the visualizer key in the config); if the config lacks it or was passed as None, visualization cannot proceed.","triggerScenarios":"Calling DetInferencer(...) with show=True, return_vis=True, or a non-empty img_out_dir, while the underlying config has no visualizer definition or the inferencer was constructed with a minimal/hand-written config missing the visualizer key.","commonSituations":"Using custom stripped-down configs, initializing the inferencer from a raw Config object rather than a full model config, or versions where visualizer setup depends on cfg.visualizer being present in the config file.","solutions":["Add a visualizer block to the config: visualizer=dict(type='DetLocalVisualizer', vis_backends=[dict(type='LocalVisBackend')], name='visualizer')","Only pass show=False / img_out_dir='' / return_vis=False (the default) if you don't need visualization, which returns None before the check","Ensure the config is a complete mmdet config (copy from an existing config in configs/ rather than writing from scratch)"],"exampleFix":"// before\ncfg = dict(model=model_cfg, test_pipeline=pipeline)  # no visualizer\ninfer = DetInferencer(cfg, weights='ckpt.pth')\nres = infer('img.jpg', show=True)\n// after\ncfg = dict(model=model_cfg, test_pipeline=pipeline,\n           visualizer=dict(type='DetLocalVisualizer',\n                           vis_backends=[dict(type='LocalVisBackend')],\n                           name='visualizer'))\ninfer = DetInferencer(cfg, weights='ckpt.pth')\nres = infer('img.jpg', show=True)","handlingStrategy":"validation","validationCode":"wants_vis = show or img_out_dir or return_vis\nif wants_vis:\n    assert inferencer.visualizer is not None, \\\n        'config has no visualizer term; add one or disable show/return_vis/img_out_dir'","typeGuard":"def can_visualize(inferencer) -> bool:\n    return inferencer.visualizer is not None","tryCatchPattern":"try:\n    vis = inferencer(inputs, return_vis=True).visualization\nexcept ValueError as e:\n    if 'visualizer' in str(e):\n        vis = None  # degrade gracefully\n    else:\n        raise","preventionTips":["Include a visualizer block in every inferencer config","Default show=False and return_vis=False in batch/service code and only enable after asserting visualizer exists","Smoke-test the config once at app startup"],"tags":["mmdetection","inferencer","visualizer","config"],"backgroundTag":"missing-config-key","analyzedSha":"cfd5d3a985b0249de009b67d04f37263e11cdf3d","analyzedAt":"2026-08-27T20:54:20.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}