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: ObjectSizeCategoryView on GitHub (pinned to 7f254d9784)
Solutions
- Pass a real enum member: MeanAverageRecall(metric_target=MetricTarget.MASKS) imported from supervision.metrics.mean_average_recall (or supervision.detection.core)
- If loading from config, validate/whitelist the value against [e.value for e in MetricTarget] before constructing the metric
- If a stale enum member from another supervision version is involved, align all environments on one supervision version
- 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
- Always construct metric_target from the MetricTarget enum, never raw strings/ints
- Validate config-sourced values with MetricTarget(value) before passing them in
- Pin one supervision version across dev/CI/prod
- Never mutate private fields like _metric_target; recreate the metric
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
- Unsupported metric target for IoU calculation
- Invalid metric target: {self._metric_target}
- The number of predictions ({len(predictions)}) and targets (
- MeanAverageRecall with `MetricTarget.MASKS` requires detecti
- MeanAverageRecall metric requires `class_id` on both predict
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/3f3556d3d86bc0e6.
Report an issue: GitHub.