{"record":{"id":"cb59c3d4051cacbe","repo":"roboflow/supervision","slug":"rgba-must-be-a-4-tuple-with-values-between-0-255","errorCode":null,"errorMessage":"RGBA must be a 4-tuple with values between 0-255.","messagePattern":"RGBA must be a 4-tuple with values between 0-255\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/annotators/utils.py","lineNumber":485,"sourceCode":"    Args:\n        rgba: RGBA values in range 0-255.\n\n    Returns:\n        Hex color string in the format \"#RRGGBBAA\".\n\n    Raises:\n        ValueError: If `rgba` is not a 4-tuple or contains values outside 0-255.\n\n    Examples:\n        ```pycon\n        >>> from supervision.annotators.utils import rgba_to_hex\n        >>> rgba_to_hex((255, 0, 255, 128))\n        '#FF00FF80'\n\n        ```\n    \"\"\"\n    if len(rgba) != 4 or not all(0 <= c <= 255 for c in rgba):\n        raise ValueError(\"RGBA must be a 4-tuple with values between 0-255.\")\n    return \"#{:02X}{:02X}{:02X}{:02X}\".format(*rgba)\n\n\ndef is_valid_hex(hex_color: str) -> bool:\n    \"\"\"\n    Checks if a given string is a valid hex color.\n\n    Args:\n        hex_color: A hex color string with an optional leading \"#\". Supports\n            6-digit (RGB) or 8-digit (RGBA) formats.\n\n    Returns:\n        True if the string is a valid 6- or 8-digit hex color, otherwise False.\n\n    Examples:\n        ```pycon\n        >>> from supervision.annotators.utils import is_valid_hex\n        >>> is_valid_hex(\"#FF00FF\")","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/annotators/utils.py#L467-L503","documentation":"Raised by `supervision.annotators.utils.rgba_to_hex` when `rgba` is not a sequence of exactly 4 values or when any component is outside 0-255. The function formats each channel as two uppercase hex digits, so out-of-range or missing channels cannot be encoded.","triggerScenarios":"Calling `rgba_to_hex((255, 0, 255))` (3-tuple), `rgba_to_hex((255, 0, 255, 256))`, `rgba_to_hex((255, -1, 0, 128))`, or passing float alpha as 1.0 instead of 255 (e.g. `rgba_to_hex((1.0, 0.5, 0.0, 1.0))` fails because 1.0 > 255 is false but 1.0 passes... actually 0 <= 1.0 <= 255 passes while 300 or 256 fails).","commonSituations":"Passing normalized 0-1 floats from matplotlib/PIL conventions where supervision expects 0-255 ints; forgetting the alpha channel when converting from an RGB tuple; off-by-one alpha computed as 256 from a percentage calculation like `int(alpha_pct * 256)`.","solutions":["Scale normalized floats to 0-255 before calling: `tuple(int(c * 255) for c in rgba_0_1)`.","Ensure exactly 4 components; append `255` if your source tuple is RGB-only.","Clamp computed channels with `min(255, max(0, round(c)))` before conversion."],"exampleFix":"# before\nrgba_to_hex((1.0, 0.0, 1.0, 0.5))  # normalized floats, wrong scale\n\n# after\nrgba_to_hex((255, 0, 255, 128))  # 0-255 ints, alpha 0.5 -> 128","handlingStrategy":"validation","validationCode":"def to_rgba255(rgba) -> tuple[int, int, int, int]:\n    rgba = tuple(int(round(c * 255)) if 0 <= c <= 1.0 and isinstance(c, float) else int(c) for c in rgba)\n    if len(rgba) != 4:\n        raise ValueError(\"expected 4 components\")\n    return tuple(min(255, max(0, c)) for c in rgba)  # type: ignore[return-value]","typeGuard":"def is_valid_rgba(v) -> bool:\n    return (\n        isinstance(v, (tuple, list))\n        and len(v) == 4\n        and all(isinstance(c, (int, float)) and 0 <= c <= 255 for c in v)\n    )","tryCatchPattern":null,"preventionTips":["Keep one convention in your codebase: 0-255 ints for supervision colors.","Convert normalized floats with int(c * 255) at the boundary."],"tags":["color","validation","annotators"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}