roboflow/supervision · error · ValueError

The number of predictions ({len(predictions)}) and targets (

Error message

The number of predictions ({len(predictions)}) and targets ({len(targets)}) during the update must be the same.

What it means

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.

Source

Thrown at src/supervision/metrics/mean_average_precision.py:1442

        targets: Detections | list[Detections],
    ) -> MeanAveragePrecision:
        """
        Add new predictions and targets to the metric, but do not compute the result.

        Args:
            predictions: The predicted detections.
            targets: The ground-truth detections.

        Returns:
            The updated metric instance.
        """
        if not isinstance(predictions, list):
            predictions = [predictions]
        if not isinstance(targets, list):
            targets = [targets]

        if len(predictions) != len(targets):
            raise ValueError(
                f"The number of predictions ({len(predictions)}) and"
                f" targets ({len(targets)}) during the update must be the same."
            )

        if self._class_agnostic:
            predictions = deepcopy(predictions)
            targets = deepcopy(targets)

            for prediction in predictions:
                if prediction.class_id is not None:
                    prediction.class_id[:] = -1
            for target in targets:
                if target.class_id is not None:
                    target.class_id[:] = -1

        self._predictions_list.extend(predictions)
        self._targets_list.extend(targets)

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Pass equal-length lists: one sv.Detections per image on both sides, using sv.Detections.empty() for frames without detections
  2. Fix accumulation loops to append to both lists in lockstep
  3. Assert len equality immediately before update() to fail with pipeline context
  4. Use zip(images, preds, targets) style loops so divergence is structurally impossible

Example fix

# before
for img, det in zip(images, detections):
    preds.append(det)
    if det is not None:
        targets.append(load_gt(img))   # conditional append -> drift
map_.update(preds, targets)

# after
for img, det in zip(images, detections):
    preds.append(det if det is not None else sv.Detections.empty())
    targets.append(load_gt(img))
map_.update(preds, targets)
Defensive patterns

Strategy: validation

Validate before calling

preds = preds if isinstance(preds, list) else [preds]
tgts = tgts if isinstance(tgts, list) else [tgts]
assert len(preds) == len(tgts), f'{len(preds)} preds vs {len(tgts)} targets'
map_.update(preds, tgts)

Type guard

from supervision.detection.core import Detections
from typing import Union, List

def is_matched_detection_inputs(
    preds: Union[Detections, List[Detections]],
    tgts: Union[Detections, List[Detections]],
) -> bool:
    """True when both sides normalize to equal-length lists."""
    p = preds if isinstance(preds, list) else [preds]
    t = tgts if isinstance(tgts, list) else [tgts]
    return len(p) == len(t)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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