roboflow/supervision · error · ValueError
The number of predictions ({total_images_predictions}) and t
Error message
The number of predictions ({total_images_predictions}) and targets ({total_images_targets}) during the evaluation must be the same. What it means
MeanAveragePrecision.compute() verifies that the accumulated prediction images and target images counts match before building the COCO evaluation. Unlike the update()-time check (error 354), this fires at evaluation time, meaning the two internal lists ended up with different lengths — typically because update() was called with matching single Detections at different times, or lists were extended unevenly across multiple update() calls.
Source
Thrown at src/supervision/metrics/mean_average_precision.py:1653
if content is not None:
dict_prediction["content"] = content[pred_idx]
coco_predictions.append(dict_prediction)
return coco_predictions
def compute(self) -> MeanAveragePrecisionResult:
"""
Calculate Mean Average Precision based on predicted and ground-truth
detections at different thresholds using the COCO evaluation metrics.
Source: https://github.com/rafaelpadilla/review_object_detection_metrics
Returns:
The Mean Average Precision result.
"""
total_images_predictions = len(self._predictions_list)
total_images_targets = len(self._targets_list)
if total_images_predictions != total_images_targets:
raise ValueError(
f"The number of predictions ({total_images_predictions}) and"
f" targets ({total_images_targets}) during the evaluation must be"
" the same."
)
dict_targets = self._prepare_targets(self._targets_list)
lst_predictions = self._prepare_predictions(self._predictions_list)
# Create a coco object with the targets
coco_gt = EvaluationDataset(targets=dict_targets)
# Include the predictions to coco object
coco_det = coco_gt.load_predictions(lst_predictions)
# Create a coco evaluator with the predictions
cocoEval = COCOEvaluator(coco_gt, coco_det, metric_target=self._metric_target)
# Evaluate on all images
cocoEval.evaluate()
# Create MeanAveragePrecisionResult object for small objects
mAP_small = MeanAveragePrecisionResult(View on GitHub (pinned to 7f254d9784)
Solutions
- Use only the public update() to add data — it validates per call
- Never mutate _predictions_list/_targets_list; create a fresh metric per experiment
- In subclasses, call super().update() or replicate the length validation
- Restart the metric object if state integrity is in doubt and re-run updates
Example fix
# before
map_._predictions_list.append(pred) # bypasses validation
map_._targets_list.extend(all_targets) # uneven -> compute() fails
map_.compute()
# after
map_ = sv.MeanAveragePrecision()
for p, t in zip(preds, targets):
map_.update(p, t) # validated per call
map_.compute() Defensive patterns
Strategy: validation
Validate before calling
assert len(map_._predictions_list) == len(map_._targets_list) or True # real guard: only use public update(); before compute check nothing extra is needed
Try / catch
try:
result = map_.compute()
except ValueError as e:
if 'must be the same' in str(e):
raise RuntimeError('metric state corrupted; rebuild metric and re-run updates') from e
raise Prevention
- Never append directly to _predictions_list/_targets_list
- Create a fresh MeanAveragePrecision per experiment/run
- In subclasses, delegate to super().update() to keep validation
When it happens
Trigger: Calling map.update(pred_a, target_a) then map.update(pred_list, target_list) with mismatched per-call counts is caught earlier — this error specifically appears when the totals diverge, e.g. update(preds, [t1]) style single-vs-list mismatches that slipped through, or direct mutation of the private _predictions_list/_targets_list; multiple update() calls each balanced individually cannot trigger it (each is validated), so this guard mostly protects internal-state corruption and direct list manipulation.
Common situations: Custom code extending _predictions_list/_targets_list directly; forks that bypass update() validation; memory of state across experiments in notebooks reusing a metric object; subclass overrides of update() that forget the length check.
Related errors
- The number of predictions ({len(predictions)}) and targets (
- The number of predictions ({len(predictions)}) and targets (
- MeanAverageRecall metric requires `class_id` on both predict
- MeanAverageRecall metric requires `confidence` on prediction
- Invalid metric target: {self._metric_target}
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/4f5eb0011dc34de0.
Report an issue: GitHub.