roboflow/supervision · error · ValueError
Expected covariance shape {expected_shape}, got {covariances
Error message
Expected covariance shape {expected_shape}, got {covariances_array.shape}. What it means
Raised by ColorPalette.by_idx when the palette's colors list is empty, before any indexing happens. A ColorPalette with zero colors cannot serve a lookup, so the method refuses rather than returning None or wrapping an empty list. Any by_idx call — including by_idx(0) — on an empty palette triggers this.
Source
Thrown at src/supervision/key_points/annotators.py:322
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():
return None
try:
eigenvalues, eigenvectors = np.linalg.eigh(covariance.astype(np.float64))
except np.linalg.LinAlgError:
return None
if not np.isfinite(eigenvalues).all() or np.any(eigenvalues <= 0):
return None
order = np.argsort(eigenvalues)[::-1]View on GitHub (pinned to 7f254d9784)
Solutions
- Ensure the colors list passed to sv.ColorPalette(...) or from_hex([...]) is non-empty.
- Default to the built-in palette when your dynamic list is empty: palette = sv.ColorPalette.from_hex(hexes) if hexes else sv.ColorPalette.DEFAULT.
- Add an early check in config-loading code that rejects or warns on empty color lists instead of constructing the palette.
- If you only need cyclic colors over unknown class counts, construct a palette of a fixed size once and rely on by_idx's modulo wrapping.
Example fix
# before palette = sv.ColorPalette.from_hex([]) # later palette.by_idx(0) raises # after palette = sv.ColorPalette.from_hex(hexes) if hexes else sv.ColorPalette.DEFAULT # or simply: palette = sv.ColorPalette.from_hex(hexes or ['#FF0000', '#00FF00', '#0000FF'])
Defensive patterns
Strategy: validation
Validate before calling
if not hex_colors:
raise ValueError(f"color list is empty; cannot build palette: {hex_colors!r}")
palette = sv.ColorPalette.from_hex(hex_colors)
# or fall back to the default palette:
# palette = sv.ColorPalette.from_hex(hex_colors or ['#FF0000', '#00FF00', '#0000FF']) Type guard
def has_colors(palette: sv.ColorPalette) -> bool:
"""True if the palette can serve by_idx lookups."""
return len(palette.colors) > 0 Prevention
- Check len(colors) > 0 before constructing ColorPalette from dynamic lists.
- Validate color config at load time (non-empty, valid hexes) so failures surface at startup, not mid-annotation.
- Keep a sensible default palette constant to fall back to when the dynamic list is empty.
When it happens
Trigger: Constructing sv.ColorPalette(colors=[]) or sv.ColorPalette.from_hex([]) then calling .by_idx(i); building palettes from a dynamically generated hex list that is empty on the first iteration; deserializing a palette from config where the colors key is an empty list.
Common situations: Palette built from per-class colors loaded from user config that is missing/empty; loop-driven palette construction where the source list is empty for some class set; downstream of from_matplotlib with color_count < 1 being caught and defaulting to an empty palette instead.
Related errors
- key_points.data must contain 'covariance' with shape (N, K,
- module {__name__} has no attribute {name}
- Edge indices must use the 1-based convention and be within t
- sigma must contain at least one value
- All sigma values must be positive
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/6b7c1709fc211450.
Report an issue: GitHub.