{"record":{"id":"e0491c9e2ec56401","repo":"roboflow/supervision","slug":"meanaveragerecall-metric-requires-confidence-on","errorCode":null,"errorMessage":"MeanAverageRecall metric requires `confidence` on predictions.","messagePattern":"MeanAverageRecall metric requires `confidence` on predictions\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/metrics/mean_average_recall.py","lineNumber":429,"sourceCode":"                        \"predictions and targets.\"\n                    )\n                if len(predictions) == 0:\n                    target_class_ids = np.asarray(targets.class_id, dtype=np.int32)\n                    if len(target_class_ids) == 0:\n                        continue\n                    stats.append(\n                        (\n                            np.zeros((0, iou_thresholds.size), dtype=bool),\n                            np.zeros((0, iou_thresholds.size), dtype=bool),\n                            np.zeros((0,), dtype=int),\n                            np.zeros((0,), dtype=int),\n                            target_class_ids,\n                        )\n                    )\n\n                else:\n                    if predictions.confidence is None:\n                        raise ValueError(\n                            \"MeanAverageRecall metric requires `confidence` on \"\n                            \"predictions.\"\n                        )\n                    prediction_class_ids = np.asarray(\n                        predictions.class_id, dtype=np.int32\n                    )\n                    target_class_ids = np.asarray(targets.class_id, dtype=np.int32)\n                    prediction_confidence = np.asarray(\n                        predictions.confidence, dtype=np.float32\n                    )\n                    if self._metric_target == MetricTarget.BOXES:\n                        # BOXES target never yields CompactMask; narrow for mypy.\n                        iou = box_iou_batch(\n                            cast(npt.NDArray[np.number], target_contents),\n                            cast(npt.NDArray[np.number], prediction_contents),\n                        )\n                    elif self._metric_target == MetricTarget.MASKS:\n                        iou = mask_iou_batch(target_contents, prediction_contents)","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/metrics/mean_average_recall.py#L411-L447","documentation":"MeanAverageRecall ranks predictions by confidence when computing recall across IoU thresholds, so predictions must carry a confidence array. This ValueError fires in compute() when, for an image that has both non-empty targets and non-empty predictions, predictions.confidence is None. Targets never need confidence; only the prediction side is checked.","triggerScenarios":"Building prediction sv.Detections from ground-truth-style data or manual boxes without confidence=; using a connector that discards scores; copying target Detections to fake predictions in a sanity test; note the guard is inside the len(predictions)>0 branch, so it triggers exactly when there is something to rank.","commonSituations":"Hand-crafted unit tests or visualizations converted into evaluation without scores; trackers (ByteTrack) whose output Detections may lack confidence unless re-attached; deterministic rule-based detectors that emit boxes with no score; assuming MAR works like a rank-free overlap metric.","solutions":["Attach a confidence array when constructing prediction Detections (even a constant ones array makes ranking well-defined)","Use a model connector that preserves scores (e.g. from_ultralytics keeps confidence)","If predictions genuinely have no scores, set confidence=np.ones(len(detections), dtype=np.float32) on both sides deliberately","Pre-check before update(): if len(preds)>0 and preds.confidence is None, raise your own descriptive error or fill defaults"],"exampleFix":"# before\npreds = sv.Detections(xyxy=boxes, class_id=ids)  # no confidence\nmar.update(preds, targets)\n\n# after\npreds = sv.Detections(xyxy=boxes, class_id=ids,\n                      confidence=np.array(scores, dtype=np.float32))\nmar.update(preds, targets)","handlingStrategy":"validation","validationCode":"import numpy as np\nfrom supervision.detection.core import Detections\n\ndef confidence_ready(preds: Detections) -> bool:\n    \"\"\"Non-empty predictions need confidence for MAR ranking.\"\"\"\n    return len(preds) == 0 or preds.confidence is not None","typeGuard":"import numpy as np\nfrom supervision.detection.core import Detections\n\ndef with_confidence(dets: Detections) -> Detections:\n    \"\"\"Return Detections guaranteed to carry confidence (default 1.0).\"\"\"\n    if dets.confidence is None and len(dets) > 0:\n        dets.confidence = np.ones(len(dets), dtype=np.float32)\n    return dets","tryCatchPattern":null,"preventionTips":["Always attach confidence when building prediction Detections from model scores","If scores are meaningless, deliberately set ones and note ranking is arbitrary","Validate preds.confidence is not None before update()"],"tags":["metrics","mean-average-recall","confidence","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}