roboflow/supervision · error · ValueError

Unsupported metric target for IoU calculation

Error message

Unsupported metric target for IoU calculation

What it means

Defensive unreachable branch in F1Score's IoU computation: the code handles MetricTarget.BOXES, MASKS, and ORIENTED_BOUNDING_BOXES, and raises if _metric_target is anything else. With the current MetricTarget enum this cannot fire; it exists so that a future enum member added without an IoU strategy fails loudly instead of silently falling through with None. Hitting it means you passed an invalid/extended metric_target value.

Source

Thrown at src/supervision/metrics/f1_score.py:262

                    prediction_confidence = np.asarray(
                        predictions.confidence, dtype=np.float32
                    )
                    if self._metric_target == MetricTarget.BOXES:
                        # BOXES target never yields CompactMask; narrow for mypy.
                        iou = box_iou_batch(
                            cast(npt.NDArray[np.number], target_contents),
                            cast(npt.NDArray[np.number], prediction_contents),
                        )
                    elif self._metric_target == MetricTarget.MASKS:
                        iou = mask_iou_batch(target_contents, prediction_contents)
                    elif self._metric_target == MetricTarget.ORIENTED_BOUNDING_BOXES:
                        # OBB target never yields CompactMask; narrow for mypy.
                        iou = oriented_box_iou_batch(
                            cast(npt.NDArray[np.number], target_contents),
                            cast(npt.NDArray[np.number], prediction_contents),
                        )
                    else:
                        raise ValueError(
                            "Unsupported metric target for IoU calculation"
                        )

                    # None keeps the matcher on its single-round fast path
                    # when no size bucket is scored.
                    target_scored_mask = (
                        target_size_mask
                        if size_category != ObjectSizeCategory.ANY
                        else None
                    )
                    matches, matched_target_indices = (
                        _match_detection_batch_with_target_indices(
                            prediction_class_ids,
                            target_class_ids,
                            iou,
                            iou_thresholds,
                            target_scored_mask=target_scored_mask,
                        )

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Use the enum: from supervision.metrics.metric_target import MetricTarget; F1Score(metric_target=MetricTarget.BOXES)
  2. Validate the value against MetricTarget before constructing the metric when it comes from external config

Example fix

# before
f1 = sv.metrics.f1_score.F1Score(metric_target=3)  # invalid raw value

# after
from supervision.metrics.metric_target import MetricTarget

f1 = sv.metrics.f1_score.F1Score(metric_target=MetricTarget.MASKS)
Defensive patterns

Strategy: type-guard

Validate before calling

from supervision.metrics.metric_target import MetricTarget

assert metric_target in (
    MetricTarget.BOXES,
    MetricTarget.MASKS,
    MetricTarget.ORIENTED_BOUNDING_BOXES,
), f'unsupported metric_target: {metric_target!r}'

Type guard

from supervision.metrics.metric_target import MetricTarget

SUPPORTED_F1_TARGETS = frozenset({
    MetricTarget.BOXES,
    MetricTarget.MASKS,
    MetricTarget.ORIENTED_BOUNDING_BOXES,
})

def is_supported_target(t: object) -> bool:
    """True when t is a MetricTarget F1Score can compute IoU for."""
    return t in SUPPORTED_F1_TARGETS

Try / catch

try:
    f1 = F1Score(metric_target=metric_target)
    f1.update(targets=t, predictions=p)
except ValueError as e:
    if 'Unsupported metric target' in str(e):
        f1 = F1Score(metric_target=MetricTarget.BOXES)  # explicit fallback choice
    else:
        raise

Prevention

When it happens

Trigger: Constructing F1Score(metric_target=cast_value) with a value not in MetricTarget (e.g. an int outside the enum, or a monkeypatched/new enum member from a mismatched supervision version).

Common situations: Passing metric_target as a raw string or int instead of the MetricTarget enum; mixing supervision versions where a custom MetricTarget member was added on one side; dynamic target selection from config that yields an invalid value.

Related errors


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