roboflow/supervision · error · ValueError

2D boolean mask column count

Error message

2D boolean mask column count {mask.shape[1]} does not match keypoint count {self.xy.shape[1]}.

What it means

F1Score._make_empty_content() returns the shaped empty array for empty Detections per metric target and, like its siblings, ends with a defensive ValueError for any MetricTarget it does not know. Reachable only with version skew or injected enum values, and only when compute() processes empty Detections.

Solutions

  1. Align the supervision version (reinstall/upgrade)
  2. Restrict metric_target to supported members
  3. Remove enum patches
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = {sv.MetricTarget.BOXES, sv.MetricTarget.MASKS, sv.MetricTarget.ORIENTED_BOUNDING_BOXES}
assert target in SUPPORTED

Type guard

def is_supported_f1_target(target: sv.MetricTarget) -> bool:
    return target in {sv.MetricTarget.BOXES, sv.MetricTarget.MASKS, sv.MetricTarget.ORIENTED_BOUNDING_BOXES}

Prevention

When it happens

Trigger: An unsupported metric_target value combined with empty predictions/targets lists during F1Score.compute().

Common situations: Version-mismatched supervision installs or monkey-patched enums, surfaced when evaluating images with zero detections.

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/baf9bb7d4e639fa1. Report an issue: GitHub.

Appendix: source

Thrown at src/supervision/key_points/core.py:870

                stored in a uniform `(n, k, ...)` array.

        Returns:
            A new `KeyPoints` instance containing only the keypoints selected by
            the mask for each object.

        Raises:
            ValueError: If `mask.shape[0]` does not match the number of objects, if
                `mask.shape[1]` does not match the number of keypoints, or if
                different rows of the mask select different numbers of `True` values.
        """
        n = len(self.xy)
        if mask.shape[0] != n:
            raise ValueError(
                f"2D boolean mask row count {mask.shape[0]} does not match "
                f"object count {n}."
            )
        if mask.shape[1] != self.xy.shape[1]:
            raise ValueError(
                f"2D boolean mask column count {mask.shape[1]} does not match "
                f"keypoint count {self.xy.shape[1]}."
            )
        counts = np.sum(mask, axis=1)
        if n > 0 and not np.all(counts == counts[0]):
            raise ValueError(
                "Cannot filter keypoints with a 2D boolean mask where rows have "
                "different numbers of True values. "
                "All objects must select the same number of keypoints. "
                f"Got counts per object: {counts.tolist()}"
            )
        k = int(counts[0]) if n > 0 else 0
        xy_selected = np.zeros((n, k, self.xy.shape[2]), dtype=self.xy.dtype)
        keypoint_confidence_selected: npt.NDArray[np.float32] | None = None
        if self.keypoint_confidence is not None:
            keypoint_confidence_selected = cast(
                npt.NDArray[np.float32],
                np.zeros((n, k), dtype=self.keypoint_confidence.dtype),

View on GitHub (pinned to 7f254d9784)