roboflow/supervision · warning · ValueError

Invalid metric target: {self._metric_target}

Error message

Invalid metric target: {self._metric_target}

What it means

MeanAverageRecall raises this ValueError from _detections_content when the configured MetricTarget is not one of BOXES, MASKS, or ORIENTED_BOUNDING_BOXES. It is an exhaustiveness guard at the end of the if/elif chain that extracts per-detection content (boxes, masks, or oriented-box coordinates). In normal use with the public MetricTarget enum it is unreachable; hitting it means the private _metric_target field was mutated or an unknown enum/int value was injected into the constructor.

Source

Thrown at src/supervision/metrics/mean_average_recall.py:698

        if self._metric_target == MetricTarget.BOXES:
            return cast(npt.NDArray[Any], detections.xyxy)
        if self._metric_target == MetricTarget.MASKS:
            if detections.mask is not None:
                # detections.mask is NDArray[bool] | CompactMask; return as-is.
                return detections.mask
            if len(detections) > 0:
                raise ValueError(
                    "MeanAverageRecall with `MetricTarget.MASKS` requires "
                    "detections to include masks."
                )
            return self._make_empty_content()
        if self._metric_target == MetricTarget.ORIENTED_BOUNDING_BOXES:
            obb = detections.data.get(ORIENTED_BOX_COORDINATES)
            if obb is not None and len(obb) > 0:
                result_obb: npt.NDArray[np.float32] = np.array(obb, dtype=np.float32)
                return result_obb
            return self._make_empty_content()
        raise ValueError(f"Invalid metric target: {self._metric_target}")

    def _make_empty_content(self) -> npt.NDArray[Any]:
        if self._metric_target == MetricTarget.BOXES:
            empty_boxes: npt.NDArray[np.float32] = np.empty((0, 4), dtype=np.float32)
            return empty_boxes

        if self._metric_target == MetricTarget.MASKS:
            empty_masks: npt.NDArray[np.bool_] = np.empty((0, 0, 0), dtype=bool)
            return empty_masks

        if self._metric_target == MetricTarget.ORIENTED_BOUNDING_BOXES:
            empty_obb: npt.NDArray[np.float32] = np.empty((0, 4, 2), dtype=np.float32)
            return empty_obb

        raise ValueError(f"Invalid metric target: {self._metric_target}")

    def _filter_detections_by_size(
        self, detections: Detections, size_category: ObjectSizeCategory

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Pass a real enum member: MeanAverageRecall(metric_target=MetricTarget.MASKS) imported from supervision.metrics.mean_average_recall (or supervision.detection.core)
  2. If loading from config, validate/whitelist the value against [e.value for e in MetricTarget] before constructing the metric
  3. If a stale enum member from another supervision version is involved, align all environments on one supervision version
  4. Do not mutate the private _metric_target attribute; recreate the metric instead

Example fix

// before
mar = MeanAverageRecall(metric_target=2)  # raw int, not an enum member
result = mar.compute()

// after
from supervision.metrics.mean_average_recall import MeanAverageRecall, MetricTarget
mar = MeanAverageRecall(metric_target=MetricTarget.ORIENTED_BOUNDING_BOXES)
result = mar.compute()
Defensive patterns

Strategy: type-guard

Validate before calling

from supervision.metrics.mean_average_recall import MetricTarget
valid = {e.value for e in MetricTarget}
assert metric_target in valid or metric_target in list(MetricTarget), f'bad target {metric_target!r}'

Type guard

from supervision.metrics.mean_average_recall import MetricTarget
from typing import Any

def is_valid_metric_target(value: Any) -> bool:
    """True when value is a MetricTarget member usable by MeanAverageRecall."""
    return isinstance(value, MetricTarget)

Try / catch

try:
    mar.compute()
except ValueError as e:
    if 'Invalid metric target' in str(e):
        raise RuntimeError(f'misconfigured metric_target: {mar._metric_target!r}') from e
    raise

Prevention

When it happens

Trigger: Constructing MeanAverageRecall(metric_target=<value not in MetricTarget>) (e.g. a raw int, a stale enum member from an older supervision version, or a monkeypatched/invalid enum), then calling .compute(); directly assigning to the private _metric_target attribute; pickling/deserializing a metric across versions where the enum changed.

Common situations: Passing metric_target as a string like 'masks' instead of MetricTarget.MASKS; using an int constant copied from old docs; version skew where a MetricTarget member was removed or renamed; test code monkeypatching internals.

Related errors


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