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

  1. Use only the public update() to add data — it validates per call
  2. Never mutate _predictions_list/_targets_list; create a fresh metric per experiment
  3. In subclasses, call super().update() or replicate the length validation
  4. 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

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


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