roboflow/supervision · error · TypeError

custom_values must be either a numpy array or a list of floa

Error message

custom_values must be either a numpy array or a list of floats.

What it means

Raised by `PercentageBarAnnotator._validate_custom_values` when `custom_values` is neither a NumPy array nor a Python list. The API accepts only those two container types so it can validate length and value range uniformly; tuples, generators, pandas Series, or scalars are rejected with a TypeError.

Source

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

            return (cx, cy), (cx + width, cy + height)
        raise ValueError(f"Unsupported position: {position}")

    @staticmethod
    def _validate_custom_values(
        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(

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Convert to a list or NumPy array: `custom_values=list(values)`, `np.asarray(values)`, `values.tolist()`, or `tensor.cpu().numpy()`.
  2. For a single detection, still pass a one-element container: `[0.7]`.
  3. Keep values in 0-1 range after conversion.

Example fix

# before
annotator.annotate(scene, detections, custom_values=scores_tensor)      # torch tensor
annotator.annotate(scene, detections, custom_values=(0.5, 0.8))          # tuple

# after
annotator.annotate(scene, detections, custom_values=scores_tensor.cpu().numpy())
annotator.annotate(scene, detections, custom_values=[0.5, 0.8])
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(custom_values, (np.ndarray, list)):
    custom_values = list(custom_values)  # materialize tuples/generators/Series

Type guard

def is_valid_custom_values(v) -> bool:
    return isinstance(v, (np.ndarray, list))

Prevention

When it happens

Trigger: Passing `custom_values=(0.5, 0.8)` (tuple), a generator, a pandas Series, a torch tensor, or a bare float to `PercentageBarAnnotator.annotate`. Each fails the `isinstance(custom_values, (np.ndarray, list))` check.

Common situations: Handing over a pandas column from a dataframe-backed pipeline; passing a torch tensor in a training-loop visualization; forgetting to materialize a generator; passing a single scalar when there is exactly one detection.

Related errors


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