{"record":{"id":"87b5dc160b592e8c","repo":"roboflow/supervision","slug":"2d-boolean-mask-row-count-mask-shape-0-does-not","errorCode":null,"errorMessage":"2D boolean mask row count {mask.shape[0]} does not match object count {n}.","messagePattern":"2D boolean mask row count (.+?) does not match object count (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/key_points/core.py","lineNumber":865,"sourceCode":"\n        Args:\n            mask: A boolean array of shape `(n, m)` where `n` is the number of\n                objects and `m` is the number of keypoints per object.  Every row\n                must select the same number of keypoints so that the result can be\n                stored in a uniform `(n, k, ...)` array.\n\n        Returns:\n            A new `KeyPoints` instance containing only the keypoints selected by\n            the mask for each object.\n\n        Raises:\n            ValueError: If `mask.shape[0]` does not match the number of objects, if\n                `mask.shape[1]` does not match the number of keypoints, or if\n                different rows of the mask select different numbers of `True` values.\n        \"\"\"\n        n = len(self.xy)\n        if mask.shape[0] != n:\n            raise ValueError(\n                f\"2D boolean mask row count {mask.shape[0]} does not match \"\n                f\"object count {n}.\"\n            )\n        if mask.shape[1] != self.xy.shape[1]:\n            raise ValueError(\n                f\"2D boolean mask column count {mask.shape[1]} does not match \"\n                f\"keypoint count {self.xy.shape[1]}.\"\n            )\n        counts = np.sum(mask, axis=1)\n        if n > 0 and not np.all(counts == counts[0]):\n            raise ValueError(\n                \"Cannot filter keypoints with a 2D boolean mask where rows have \"\n                \"different numbers of True values. \"\n                \"All objects must select the same number of keypoints. \"\n                f\"Got counts per object: {counts.tolist()}\"\n            )\n        k = int(counts[0]) if n > 0 else 0\n        xy_selected = np.zeros((n, k, self.xy.shape[2]), dtype=self.xy.dtype)","sourceCodeStart":847,"sourceCodeEnd":883,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/key_points/core.py#L847-L883","documentation":"F1Score._detections_content() mirrors Precision's: it extracts boxes, masks, or oriented boxes from Detections by metric target and raises for any MetricTarget beyond BOXES, MASKS, and ORIENTED_BOUNDING_BOXES. With the current enum the branch is unreachable defensive code that fails fast on unsupported/injected targets.","triggerScenarios":"Constructing sv.F1Score(metric_target=<unsupported or future MetricTarget member>) in a version-skewed environment or with a patched enum, then calling update()/compute() with non-empty Detections.","commonSituations":"Mixed supervision versions after partial upgrades; custom enum values passed as metric_target.","solutions":["Use a consistent, single supervision version across the project","Use only BOXES, MASKS, or ORIENTED_BOUNDING_BOXES for F1Score","Remove custom metric_target injections"],"exampleFix":"# before\nf1 = sv.F1Score(metric_target=unsupported_target)  # -> ValueError on compute\n\n# after\nf1 = sv.F1Score(metric_target=sv.MetricTarget.BOXES)","handlingStrategy":"validation","validationCode":"SUPPORTED = {sv.MetricTarget.BOXES, sv.MetricTarget.MASKS, sv.MetricTarget.ORIENTED_BOUNDING_BOXES}\nassert target in SUPPORTED, 'F1Score does not support this metric target'","typeGuard":"def is_supported_f1_target(target: sv.MetricTarget) -> bool:\n    return target in {sv.MetricTarget.BOXES, sv.MetricTarget.MASKS, sv.MetricTarget.ORIENTED_BOUNDING_BOXES}","tryCatchPattern":null,"preventionTips":["Choose the metric target from the data you actually have (boxes/masks/OBB), not aspirational capability","Keep supervision pinned to a single version"],"tags":["metrics","f1-score","metric-target","defensive-code"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}