{"record":{"id":"0810a42e20b99be8","repo":"roboflow/supervision","slug":"key-points-data-must-contain-covariance-with-sha","errorCode":null,"errorMessage":"key_points.data must contain 'covariance' with shape (N, K, 2, 2).","messagePattern":"key_points\\.data must contain 'covariance' with shape \\(N, K, 2, 2\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/key_points/annotators.py","lineNumber":314,"sourceCode":"        if max_axis is not None and max_axis <= 0:\n            raise ValueError(\"max_axis must be positive when provided\")\n        if len(color_seq) != len(sigma_seq):\n            raise ValueError(\n                f\"color length ({len(color_seq)}) must match \"\n                f\"sigma length ({len(sigma_seq)})\"\n            )\n\n        sorted_indices = sorted(\n            range(len(sigma_seq)), key=lambda i: sigma_seq[i], reverse=True\n        )\n        self.sigma = [sigma_seq[i] for i in sorted_indices]\n        self.color = [color_seq[i] for i in sorted_indices]\n        self.max_axis = max_axis\n\n    def _get_covariances(self, key_points: KeyPoints) -> npt.NDArray[np.float32]:\n        covariances = key_points.data.get(\"covariance\")\n        if covariances is None:\n            raise ValueError(\n                \"key_points.data must contain 'covariance' with shape (N, K, 2, 2).\"\n            )\n        covariances_array = cast(\n            npt.NDArray[np.float32], np.asarray(covariances, dtype=np.float32)\n        )\n        expected_shape = (*key_points.xy.shape[:2], 2, 2)\n        if covariances_array.shape != expected_shape:\n            raise ValueError(\n                f\"Expected covariance shape {expected_shape}, \"\n                f\"got {covariances_array.shape}.\"\n            )\n        return covariances_array\n\n    def _decompose_covariance(\n        self, covariance: npt.NDArray[np.float32]\n    ) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]] | None:\n        \"\"\"Eigendecompose a 2x2 covariance, returning sorted (eigenvalues, vectors).\"\"\"\n        if not np.isfinite(covariance).all():","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/key_points/annotators.py#L296-L332","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Guard dynamic counts: use max(1, number_of_classes) or skip palette creation when the count is 0.","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.","Check the variable feeding color_count before the call and log when it is non-positive — it usually indicates empty input data upstream."],"exampleFix":"# before\npalette = sv.ColorPalette.from_matplotlib('viridis', len(class_names))  # raises when empty\n\n# after\npalette = (\n    sv.ColorPalette.from_matplotlib('viridis', max(1, len(class_names)))\n    if class_names\n    else sv.ColorPalette.from_matplotlib('viridis', 10)\n)","handlingStrategy":"validation","validationCode":"count = len(class_names)\nif count < 1:\n    raise RuntimeError(f\"cannot build palette: got {count} classes\")\npalette = sv.ColorPalette.from_matplotlib('viridis', count)\n\n# or simply clamp:\n# palette = sv.ColorPalette.from_matplotlib('viridis', max(1, count))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass a raw len(...) that can be 0 (empty scene, first frame, empty dataset) — clamp with max(1, n).","Build one fixed-size palette up front and use by_idx's modulo wrapping for unknown class counts.","Treat color_count <= 0 as a data problem upstream: log it rather than silently clamping in production paths."],"tags":["validation","color-palette","matplotlib","valueerror"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}