roboflow/supervision · error · ValueError

Detections confidence must be given for NMS to be executed.

Error message

Detections confidence must be given for NMS to be executed.

What it means

Detections.with_nms performs non-maximum suppression, which ranks boxes by confidence. Without a confidence array there is no way to decide which box in an overlap group survives, so the method raises this ValueError when self.confidence is None.

Solutions

  1. If scores exist upstream, attach them: cls(xyxy=..., confidence=scores, ...).
  2. If you want to suppress purely on IoU without scores, implement selection manually (e.g. sv.utils.iou_and_nms or cv2.dnn.NMSBoxes with a dummy uniform score) — uniform scores make NMS keep first-of-group.
  3. For VLM results that genuinely have no confidence, skip with_nms or deduplicate by class_name text.

Example fix

# before
detections = sv.Detections(xyxy=boxes, mask=masks)  # from SAM, no confidence
clean = detections.with_nms(threshold=0.5)  # ValueError

# after
detections = sv.Detections(
    xyxy=boxes,
    mask=masks,
    confidence=np.ones(len(boxes), dtype=float),  # uniform scores for IoU-only NMS
)
clean = detections.with_nms(threshold=0.5)
Defensive patterns

Strategy: validation

Validate before calling

def with_confidence_or_default(dets: sv.Detections):
    if dets.confidence is None:
        dets = dets.__class__(
            xyxy=dets.xyxy,
            mask=dets.mask,
            class_id=dets.class_id,
            confidence=np.ones(len(dets), dtype=float),
        )
    return dets

clean = with_confidence_or_default(detections).with_nms(threshold=0.5)

Type guard

def has_confidence(dets: sv.Detections) -> bool:
    return dets.confidence is not None

Try / catch

try:
    clean = detections.with_nms(threshold=0.5)
except ValueError as e:
    if 'confidence must be given' in str(e):
        raise ValueError('source produced no scores; NMS undefined') from e
    raise

Prevention

When it happens

Trigger: Calling detections.with_nms(threshold=...) on a Detections created without confidence — e.g. from connectors that don't produce scores (from_sam, some VLM paths like PaliGemma/DeepSeek/Moondream), or manual cls(xyxy=..., class_id=...) construction.

Common situations: SAM/SAM2 segmentation masks have no scores; VLM connectors return class names without probabilities; filtering tracker output that dropped the confidence column.

Related errors


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

Appendix: source

Thrown at src/supervision/detection/core.py:3039

            class_agnostic: Whether to perform class-agnostic
                non-maximum suppression. If True, the class_id of each detection
                will be ignored. Defaults to False.
            overlap_metric: Metric used to compute the degree of
                overlap between pairs of masks or boxes (e.g., IoU, IoS).

        Returns:
            A new Detections object containing the subset of detections
                after non-maximum suppression.

        Raises:
            ValueError: If `confidence` is None and class_agnostic is False.
                If `class_id` is None and class_agnostic is False.
        """
        if len(self) == 0:
            return self

        if self.confidence is None:
            raise ValueError(
                "Detections confidence must be given for NMS to be executed."
            )

        predictions = self._build_nms_predictions(class_agnostic, "NMS")

        if self.mask is not None:
            indices = mask_non_max_suppression(
                predictions=predictions,
                masks=self.mask,
                iou_threshold=threshold,
                overlap_metric=overlap_metric,
            )
        elif ORIENTED_BOX_COORDINATES in self.data:
            indices = oriented_box_non_max_suppression(
                predictions=predictions,
                oriented_boxes=np.asarray(
                    self.data[ORIENTED_BOX_COORDINATES], dtype=np.float32
                ),

View on GitHub (pinned to 7f254d9784)