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
MeanAverageRecall.update() accepts either a single Detections or a list of Detections for predictions and targets, but the two arguments must describe the same images. This ValueError fires when, after list-wrapping, len(predictions) != len(targets) — i.e. you passed a different number of prediction frames than ground-truth frames. The metric pairs them index-by-index, so a mismatch would silently misalign evaluations, hence the hard failure.
Source
Thrown at src/supervision/metrics/mean_average_recall.py:355
targets: Detections | list[Detections],
) -> MeanAverageRecall:
"""
Add new predictions and targets to the metric, but do not compute the result.
Args:
predictions: The predicted detections.
targets: The target 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."
)
self._predictions_list.extend(predictions)
self._targets_list.extend(targets)
return self
def compute(self) -> MeanAverageRecallResult:
"""
Calculate the Mean Average Recall metric based on the stored predictions
and ground-truth, at different IoU thresholds and maximum detection counts.
Returns:
The Mean Average Recall metric result.
"""
result = self._compute(self._predictions_list, self._targets_list)View on GitHub (pinned to 7f254d9784)
Solutions
- Ensure both arguments are lists of equal length, one entry per image: mar.update(list_of_preds, list_of_targets) with len equal
- If a frame has no predictions, still pass an empty sv.Detections.empty() placeholder so indexes stay aligned
- Audit accumulation loops: append to both lists in the same iteration, never conditionally to one
- Add an assert len(preds)==len(targets) before update() in pipeline code to fail at the call site with your own context
Example fix
# before
for frame in frames:
preds.append(model(frame))
if frame.has_annotation: # targets appended conditionally -> length drift
targets.append(frame.targets)
mar.update(preds, targets)
# after
for frame in frames:
preds.append(model(frame))
targets.append(frame.targets if frame.has_annotation else sv.Detections.empty())
assert len(preds) == len(targets)
mar.update(preds, targets) Defensive patterns
Strategy: validation
Validate before calling
from supervision.detection.core import Detections
def safe_update(mar, preds, tgts):
"""Update MAR only when per-image counts align."""
preds = preds if isinstance(preds, list) else [preds]
tgts = tgts if isinstance(tgts, list) else [tgts]
if len(preds) != len(tgts):
raise ValueError(f'{len(preds)} preds vs {len(tgts)} targets')
return mar.update(preds, tgts) Type guard
from typing import Union, List
from supervision.detection.core import Detections
def is_paired_detection_lists(
preds: Union[Detections, List[Detections]],
tgts: Union[Detections, List[Detections]],
) -> bool:
"""True when both sides normalize to equal-length per-image lists."""
p = preds if isinstance(preds, list) else [preds]
t = tgts if isinstance(tgts, list) else [tgts]
return len(p) == len(t) Prevention
- Append predictions and targets in the same loop iteration
- Use sv.Detections.empty() placeholders for frames with no detections
- Assert equal lengths right before update()
When it happens
Trigger: Calling mar.update([pred1, pred2], [target1]) or mar.update(preds_list, targets_list) where the lists have different lengths; wrapping only one side in a list (update([p], t) on a non-empty target with empty predictions list vs single Detections); accumulating predictions in a loop but appending targets only on some frames.
Common situations: Streaming video frames where the model skips frames (NVR dropout, inference exceptions swallowed) so prediction list grows slower than targets; batching predictions per image but passing all targets as one Detections; off-by-one when appending the first/last frame.
Related errors
- MeanAverageRecall metric requires `class_id` on both predict
- MeanAverageRecall metric requires `confidence` on prediction
- The number of predictions ({len(predictions)}) and targets (
- Invalid metric target: {self._metric_target}
- MeanAverageRecall with `MetricTarget.MASKS` requires detecti
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/715ca2abd259d160.
Report an issue: GitHub.