{"record":{"id":"65250ad58eda8cb0","repo":"roboflow/supervision","slug":"sigma-must-contain-at-least-one-value","errorCode":null,"errorMessage":"sigma must contain at least one value","messagePattern":"sigma must contain at least one value","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/key_points/annotators.py","lineNumber":293,"sourceCode":"    \"\"\"Private base for ellipse-based keypoint annotators.\n\n    Handles sigma/color validation, sorting, covariance extraction and\n    eigendecomposition shared by all VertexEllipse* variants.\n    \"\"\"\n\n    def __init__(\n        self,\n        sigma: float | Sequence[float] = (1.0, 2.0, 3.0),\n        color: Color | Sequence[Color] = (Color.GREEN, Color.YELLOW, Color.RED),\n        max_axis: float | None = None,\n    ) -> None:\n        sigma_seq: Sequence[float] = (\n            (sigma,) if isinstance(sigma, (int, float)) else sigma\n        )\n        color_seq: Sequence[Color] = (color,) if isinstance(color, Color) else color\n\n        if len(sigma_seq) == 0:\n            raise ValueError(\"sigma must contain at least one value\")\n        if any(s <= 0 for s in sigma_seq):\n            raise ValueError(\"All sigma values must be positive\")\n        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]:","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/key_points/annotators.py#L275-L311","documentation":"Raised by sv.Color.from_rgb_tuple when any element of the (r, g, b) tuple falls outside 0-255. The method validates before delegating to the Color constructor, giving an RGB-specific message with the offending values. This guards the common path where annotators receive colors from external sources as tuples.","triggerScenarios":"sv.Color.from_rgb_tuple((300, 0, 0)), sv.Color.from_rgb_tuple((-10, 128, 128)), or passing float tuples like (1.0, 0.5, 0.0) from a library using normalized colors (values equal to 1.0 pass the range check but are floats and semantically wrong).","commonSituations":"Interfacing with matplotlib, seaborn, or plotly which express colors as 0-1 floats; reading RGB values from JSON/YAML configs without validation; math on channel values that overflows; mixing up 0-255 and 0-1 conventions in a multi-library pipeline.","solutions":["If values are normalized 0-1 floats, convert first: tuple(int(round(v * 255)) for v in rgb).","Clamp integer inputs to 0-255 before calling from_rgb_tuple.","Check for negative values coming from arithmetic (subtraction, alpha blending) in your color pipeline.","Add unit-test or runtime assertions on color tuples ingested from external data sources."],"exampleFix":"# before\ncolor = sv.Color.from_rgb_tuple((1.0, 0.4, 0.0))  # 0-1 floats -> passes range but wrong; 256.0 would raise\n\n# after\nrgb_255 = tuple(int(round(v * 255)) for v in (1.0, 0.4, 0.0))\ncolor = sv.Color.from_rgb_tuple(rgb_255)","handlingStrategy":"validation","validationCode":"def to_rgb255(rgb: tuple[float, float, float]) -> tuple[int, int, int]:\n    \"\"\"Convert 0-1 float or 0-255 numeric RGB to a valid from_rgb_tuple input.\"\"\"\n    vals = [int(round(v * 255)) if isinstance(v, float) and v <= 1.0 else int(round(v)) for v in rgb]\n    return tuple(max(0, min(255, v)) for v in vals)  # type: ignore[return-value]","typeGuard":"def is_valid_rgb_tuple(t: tuple) -> bool:\n    \"\"\"True if t is three numbers each within 0-255.\"\"\"\n    return len(t) == 3 and all(isinstance(v, (int, float)) and 0 <= v <= 255 for v in t)","tryCatchPattern":null,"preventionTips":["Establish one convention (0-255 ints) in your codebase and convert from foreign conventions (matplotlib floats, CSS) in exactly one place.","Clamp after any channel arithmetic (blending, brightening) before calling from_rgb_tuple.","Log the offending tuple when validation fails so config typos surface quickly."],"tags":["validation","color","rgb","range","valueerror"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}