roboflow/supervision · error · ValueError

The length of custom_values must match the number of detecti

Error message

The length of custom_values must match the number of detections.

What it means

Raised by `PercentageBarAnnotator._validate_custom_values` when `custom_values` is a list/array but its length differs from the number of detections. Each bar is drawn per detection, so the values must align 1:1 with `detections`; a mismatch would silently skip or misattribute bars, hence the early failure.

Source

Thrown at src/supervision/annotators/core.py:2989

        custom_values: npt.NDArray[np.float64] | list[float] | None,
        detections: Detections,
    ) -> None:
        if custom_values is None:
            if detections.confidence is None:
                raise ValueError(
                    "The provided detections do not contain confidence values. "
                    "Please provide `custom_values` or ensure that the detections "
                    "contain confidence values (e.g. by using a different model)."
                )

        else:
            if not isinstance(custom_values, (np.ndarray, list)):
                raise TypeError(
                    "custom_values must be either a numpy array or a list of floats."
                )

            if len(custom_values) != len(detections):
                raise ValueError(
                    "The length of custom_values must match the number of detections."
                )

            if not all(0 <= value <= 1 for value in custom_values):
                raise ValueError("All values in custom_values must be between 0 and 1.")

    @staticmethod
    @deprecated(  # type: ignore[untyped-decorator]
        target=_validate_custom_values.__func__,  # type: ignore[attr-defined]
        deprecated_in="0.29.0",
        remove_in="0.32.0",
    )
    def validate_custom_values(
        custom_values: npt.NDArray[np.float64] | list[float] | None,
        detections: Detections,
    ) -> None:
        void(custom_values, detections)

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Build custom_values after the last filtering step so `len(custom_values) == len(detections)`.
  2. For class-level values, expand to per-detection: `[class_score[c] for c in detections.class_id]`.
  3. Apply the same boolean mask used on detections to the values array.

Example fix

# before
values = np.array([0.9, 0.4, 0.7, 0.2, 0.5])
detections = detections[detections.confidence > 0.3]  # len changed
annotator.annotate(scene, detections, custom_values=values)  # ValueError

# after
keep = detections.confidence > 0.3
values = values[keep]
detections = detections[keep]
annotator.annotate(scene, detections, custom_values=values)
Defensive patterns

Strategy: validation

Validate before calling

custom_values = np.asarray(custom_values)
assert len(custom_values) == len(detections), (
    f"{len(custom_values)} values for {len(detections)} detections"
)

Prevention

When it happens

Trigger: Passing `custom_values=[0.9, 0.4]` to annotate 5 detections; filtering detections after building the values array; computing per-class values (length = number of classes) instead of per-detection values; combining detections from two frames while reusing one values array.

Common situations: Detections resized by confidence filtering or NMS between metric computation and annotation; per-class aggregates mistaken for per-detection values; multi-camera loops reusing a cached values array.

Related errors


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