roboflow/supervision · error · ValueError

key_points.data must contain 'covariance' with shape (N, K,

Error message

key_points.data must contain 'covariance' with shape (N, K, 2, 2).

What it means

Raised by sv.ColorPalette.from_matplotlib when its color_count argument is less than 1. The method maps a matplotlib colormap (viridis, plasma, etc.) onto exactly color_count discrete colors; zero or negative counts make that mapping (and matplotlib's resample) meaningless, so it fails fast. Note this validation runs before matplotlib is even imported.

Source

Thrown at src/supervision/key_points/annotators.py:314

        if max_axis is not None and max_axis <= 0:
            raise ValueError("max_axis must be positive when provided")
        if len(color_seq) != len(sigma_seq):
            raise ValueError(
                f"color length ({len(color_seq)}) must match "
                f"sigma length ({len(sigma_seq)})"
            )

        sorted_indices = sorted(
            range(len(sigma_seq)), key=lambda i: sigma_seq[i], reverse=True
        )
        self.sigma = [sigma_seq[i] for i in sorted_indices]
        self.color = [color_seq[i] for i in sorted_indices]
        self.max_axis = max_axis

    def _get_covariances(self, key_points: KeyPoints) -> npt.NDArray[np.float32]:
        covariances = key_points.data.get("covariance")
        if covariances is None:
            raise ValueError(
                "key_points.data must contain 'covariance' with shape (N, K, 2, 2)."
            )
        covariances_array = cast(
            npt.NDArray[np.float32], np.asarray(covariances, dtype=np.float32)
        )
        expected_shape = (*key_points.xy.shape[:2], 2, 2)
        if covariances_array.shape != expected_shape:
            raise ValueError(
                f"Expected covariance shape {expected_shape}, "
                f"got {covariances_array.shape}."
            )
        return covariances_array

    def _decompose_covariance(
        self, covariance: npt.NDArray[np.float32]
    ) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]] | None:
        """Eigendecompose a 2x2 covariance, returning sorted (eigenvalues, vectors)."""
        if not np.isfinite(covariance).all():

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Guard dynamic counts: use max(1, number_of_classes) or skip palette creation when the count is 0.
  2. If classes are unknown upfront, create the palette once with a fixed size (the default palette) and index it with by_idx, which wraps via modulo.
  3. Check the variable feeding color_count before the call and log when it is non-positive — it usually indicates empty input data upstream.

Example fix

# before
palette = sv.ColorPalette.from_matplotlib('viridis', len(class_names))  # raises when empty

# after
palette = (
    sv.ColorPalette.from_matplotlib('viridis', max(1, len(class_names)))
    if class_names
    else sv.ColorPalette.from_matplotlib('viridis', 10)
)
Defensive patterns

Strategy: validation

Validate before calling

count = len(class_names)
if count < 1:
    raise RuntimeError(f"cannot build palette: got {count} classes")
palette = sv.ColorPalette.from_matplotlib('viridis', count)

# or simply clamp:
# palette = sv.ColorPalette.from_matplotlib('viridis', max(1, count))

Prevention

When it happens

Trigger: sv.ColorPalette.from_matplotlib('viridis', 0), passing len([]) or len(unique_classes) when no detections/classes exist yet, or a config-driven count that defaults to 0 before data loads.

Common situations: Sizing the palette dynamically from the number of detected classes or tracked IDs, which is 0 on the first frame or in an empty scene; computing counts from empty datasets; off-by-one errors when deriving count from a list length minus one.

Related errors


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