{"record":{"id":"f445a0202db680bf","repo":"open-mmlab/mmdetection","slug":"only-supports-dict-or-list-or-tensor-but-get-typ","errorCode":null,"errorMessage":"Only supports dict or list or Tensor, but get {type(results)}.","messagePattern":"Only supports dict or list or Tensor, but get (.+?)\\.","errorType":"validation","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"mmdet/models/utils/misc.py","lineNumber":352,"sourceCode":"    valid_idxs = torch.nonzero(valid_mask)\n\n    num_topk = min(topk, valid_idxs.size(0))\n    # torch.sort is actually faster than .topk (at least on GPUs)\n    scores, idxs = scores.sort(descending=True)\n    scores = scores[:num_topk]\n    topk_idxs = valid_idxs[idxs[:num_topk]]\n    keep_idxs, labels = topk_idxs.unbind(dim=1)\n\n    filtered_results = None\n    if results is not None:\n        if isinstance(results, dict):\n            filtered_results = {k: v[keep_idxs] for k, v in results.items()}\n        elif isinstance(results, list):\n            filtered_results = [result[keep_idxs] for result in results]\n        elif isinstance(results, torch.Tensor):\n            filtered_results = results[keep_idxs]\n        else:\n            raise NotImplementedError(f'Only supports dict or list or Tensor, '\n                                      f'but get {type(results)}.')\n    return scores, labels, keep_idxs, filtered_results\n\n\ndef center_of_mass(mask, esp=1e-6):\n    \"\"\"Calculate the centroid coordinates of the mask.\n\n    Args:\n        mask (Tensor): The mask to be calculated, shape (h, w).\n        esp (float): Avoid dividing by zero. Default: 1e-6.\n\n    Returns:\n        tuple[Tensor]: the coordinates of the center point of the mask.\n\n            - center_h (Tensor): the center point of the height.\n            - center_w (Tensor): the center point of the width.\n    \"\"\"\n    h, w = mask.shape","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/open-mmlab/mmdetection/blob/cfd5d3a985b0249de009b67d04f37263e11cdf3d/mmdet/models/utils/misc.py#L334-L370","documentation":"filter_scores_and_topk applies keep_idxs to the results (scores/bboxes) and only handles dict, list, and torch.Tensor container types. Any other type (e.g. numpy array or tuple) raises NotImplementedError in the dense-head prediction path.","triggerScenarios":"A dense head (e.g. FCOS/RTMDet) predict path where the per-level results object passed alongside scores is not a dict/list/Tensor — typically from a custom head returning a tuple or ndarray.","commonSituations":"Custom dense heads overriding predict_by_feat_single and returning results in a non-standard container, then routing through filter_scores_and_topk.","solutions":["Return results as a dict (standard: {'bboxes':..., 'scores':...}), list, or Tensor from custom head code","Convert numpy arrays with torch.from_numpy before passing through","Match the return container convention of built-in heads when subclassing"],"exampleFix":"# before (custom head)\nreturn scores, labels, tuple(bboxes, centerness)\n# after\nreturn {'bboxes': bboxes, 'centerness': centerness}  # dict container","handlingStrategy":"type-guard","validationCode":"import torch\nassert isinstance(results, (dict, list, torch.Tensor)), type(results)","typeGuard":"def is_supported_results(r) -> bool:\n    import torch\n    return isinstance(r, (dict, list, torch.Tensor))","tryCatchPattern":"try:\n    out = filter_scores_and_topk(scores, kernel, topk, results=results)\nexcept NotImplementedError:\n    results = {'bboxes': results}\n    out = filter_scores_and_topk(scores, kernel, topk, results=results)","preventionTips":["Follow the dict return convention in custom dense heads","Never return tuples/ndarrays from predict_by_feat_single"],"tags":["mmdetection","dense-head","topk","type-validation"],"backgroundTag":"unsupported-type","analyzedSha":"cfd5d3a985b0249de009b67d04f37263e11cdf3d","analyzedAt":"2026-08-27T20:54:20.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}