{"record":{"id":"3c1d926edda3b841","repo":"roboflow/supervision","slug":"the-number-of-predictions-len-predictions-and-3c1d92","errorCode":null,"errorMessage":"The number of predictions ({len(predictions)}) and targets ({len(targets)}) during the update must be the same.","messagePattern":"The number of predictions \\((.+?)\\) and targets \\((.+?)\\) during the update must be the same\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/metrics/mean_average_precision.py","lineNumber":1442,"sourceCode":"        targets: Detections | list[Detections],\n    ) -> MeanAveragePrecision:\n        \"\"\"\n        Add new predictions and targets to the metric, but do not compute the result.\n\n        Args:\n            predictions: The predicted detections.\n            targets: The ground-truth detections.\n\n        Returns:\n            The updated metric instance.\n        \"\"\"\n        if not isinstance(predictions, list):\n            predictions = [predictions]\n        if not isinstance(targets, list):\n            targets = [targets]\n\n        if len(predictions) != len(targets):\n            raise ValueError(\n                f\"The number of predictions ({len(predictions)}) and\"\n                f\" targets ({len(targets)}) during the update must be the same.\"\n            )\n\n        if self._class_agnostic:\n            predictions = deepcopy(predictions)\n            targets = deepcopy(targets)\n\n            for prediction in predictions:\n                if prediction.class_id is not None:\n                    prediction.class_id[:] = -1\n            for target in targets:\n                if target.class_id is not None:\n                    target.class_id[:] = -1\n\n        self._predictions_list.extend(predictions)\n        self._targets_list.extend(targets)\n","sourceCodeStart":1424,"sourceCodeEnd":1460,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/metrics/mean_average_precision.py#L1424-L1460","documentation":"MeanAveragePrecision.update() mirrors the recall metric's contract: predictions and targets may each be a single Detections or a list of Detections, but after list-wrapping the counts must be equal because entries are paired per image. This ValueError fires when len(predictions) != len(targets) at update time, before any internal class-agnostic rewriting happens.","triggerScenarios":"map.update([p1, p2, p3], [t1, t2]); passing a list on one side and a single Detections on the other when counts mismatch; loop bugs appending to only one accumulator; skipping empty prediction frames in one list but not the other.","commonSituations":"Video pipelines dropping frames on inference errors; batching inference results but flattening targets differently; index drift after filtering images (e.g. removing corrupt images from targets only); notebooks incrementally built lists across cells.","solutions":["Pass equal-length lists: one sv.Detections per image on both sides, using sv.Detections.empty() for frames without detections","Fix accumulation loops to append to both lists in lockstep","Assert len equality immediately before update() to fail with pipeline context","Use zip(images, preds, targets) style loops so divergence is structurally impossible"],"exampleFix":"# before\nfor img, det in zip(images, detections):\n    preds.append(det)\n    if det is not None:\n        targets.append(load_gt(img))   # conditional append -> drift\nmap_.update(preds, targets)\n\n# after\nfor img, det in zip(images, detections):\n    preds.append(det if det is not None else sv.Detections.empty())\n    targets.append(load_gt(img))\nmap_.update(preds, targets)","handlingStrategy":"validation","validationCode":"preds = preds if isinstance(preds, list) else [preds]\ntgts = tgts if isinstance(tgts, list) else [tgts]\nassert len(preds) == len(tgts), f'{len(preds)} preds vs {len(tgts)} targets'\nmap_.update(preds, tgts)","typeGuard":"from supervision.detection.core import Detections\nfrom typing import Union, List\n\ndef is_matched_detection_inputs(\n    preds: Union[Detections, List[Detections]],\n    tgts: Union[Detections, List[Detections]],\n) -> bool:\n    \"\"\"True when both sides normalize to equal-length lists.\"\"\"\n    p = preds if isinstance(preds, list) else [preds]\n    t = tgts if isinstance(tgts, list) else [tgts]\n    return len(p) == len(t)","tryCatchPattern":null,"preventionTips":["Accumulate predictions and targets in lockstep per image","Use sv.Detections.empty() for prediction-less frames","Assert count equality before each update()"],"tags":["metrics","mean-average-precision","validation","input-shape","api-misuse"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}