{"record":{"id":"3f3556d3d86bc0e6","repo":"roboflow/supervision","slug":"invalid-metric-target-self-metric-target","errorCode":null,"errorMessage":"Invalid metric target: {self._metric_target}","messagePattern":"Invalid metric target: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"src/supervision/metrics/mean_average_recall.py","lineNumber":698,"sourceCode":"        if self._metric_target == MetricTarget.BOXES:\n            return cast(npt.NDArray[Any], detections.xyxy)\n        if self._metric_target == MetricTarget.MASKS:\n            if detections.mask is not None:\n                # detections.mask is NDArray[bool] | CompactMask; return as-is.\n                return detections.mask\n            if len(detections) > 0:\n                raise ValueError(\n                    \"MeanAverageRecall with `MetricTarget.MASKS` requires \"\n                    \"detections to include masks.\"\n                )\n            return self._make_empty_content()\n        if self._metric_target == MetricTarget.ORIENTED_BOUNDING_BOXES:\n            obb = detections.data.get(ORIENTED_BOX_COORDINATES)\n            if obb is not None and len(obb) > 0:\n                result_obb: npt.NDArray[np.float32] = np.array(obb, dtype=np.float32)\n                return result_obb\n            return self._make_empty_content()\n        raise ValueError(f\"Invalid metric target: {self._metric_target}\")\n\n    def _make_empty_content(self) -> npt.NDArray[Any]:\n        if self._metric_target == MetricTarget.BOXES:\n            empty_boxes: npt.NDArray[np.float32] = np.empty((0, 4), dtype=np.float32)\n            return empty_boxes\n\n        if self._metric_target == MetricTarget.MASKS:\n            empty_masks: npt.NDArray[np.bool_] = np.empty((0, 0, 0), dtype=bool)\n            return empty_masks\n\n        if self._metric_target == MetricTarget.ORIENTED_BOUNDING_BOXES:\n            empty_obb: npt.NDArray[np.float32] = np.empty((0, 4, 2), dtype=np.float32)\n            return empty_obb\n\n        raise ValueError(f\"Invalid metric target: {self._metric_target}\")\n\n    def _filter_detections_by_size(\n        self, detections: Detections, size_category: ObjectSizeCategory","sourceCodeStart":680,"sourceCodeEnd":716,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/metrics/mean_average_recall.py#L680-L716","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nmar = MeanAverageRecall(metric_target=2)  # raw int, not an enum member\nresult = mar.compute()\n\n// after\nfrom supervision.metrics.mean_average_recall import MeanAverageRecall, MetricTarget\nmar = MeanAverageRecall(metric_target=MetricTarget.ORIENTED_BOUNDING_BOXES)\nresult = mar.compute()","handlingStrategy":"type-guard","validationCode":"from supervision.metrics.mean_average_recall import MetricTarget\nvalid = {e.value for e in MetricTarget}\nassert metric_target in valid or metric_target in list(MetricTarget), f'bad target {metric_target!r}'","typeGuard":"from supervision.metrics.mean_average_recall import MetricTarget\nfrom typing import Any\n\ndef is_valid_metric_target(value: Any) -> bool:\n    \"\"\"True when value is a MetricTarget member usable by MeanAverageRecall.\"\"\"\n    return isinstance(value, MetricTarget)","tryCatchPattern":"try:\n    mar.compute()\nexcept ValueError as e:\n    if 'Invalid metric target' in str(e):\n        raise RuntimeError(f'misconfigured metric_target: {mar._metric_target!r}') from e\n    raise","preventionTips":["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"],"tags":["metrics","mean-average-recall","enum","validation","exhaustiveness-guard"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}