roboflow/supervision · error · ValueError

Invalid hex color format: {hex_color}

Error message

Invalid hex color format: {hex_color}

What it means

Raised by `supervision.annotators.utils.hex_to_rgba` when the input string, after stripping whitespace and removing an optional leading '#', is neither 6 characters (RGB) nor 8 characters (RGBA). The library normalizes 6-digit hex to 8 digits by appending 'FF' (full opacity); any other length is rejected because it cannot be split into RRGGBBAA byte pairs.

Source

Thrown at src/supervision/annotators/utils.py:452

    Raises:
        ValueError: If the format is invalid.

    Examples:
        ```pycon
        >>> from supervision.annotators.utils import hex_to_rgba
        >>> hex_to_rgba("#FF00FF")
        (255, 0, 255, 255)
        >>> hex_to_rgba("#FF00FF80")
        (255, 0, 255, 128)

        ```
    """
    hex_color = hex_color.strip().removeprefix("#")
    if len(hex_color) == 6:
        hex_color += "FF"  # default full opacity
    if len(hex_color) != 8:
        raise ValueError(f"Invalid hex color format: {hex_color}")
    try:
        r = int(hex_color[0:2], 16)
        g = int(hex_color[2:4], 16)
        b = int(hex_color[4:6], 16)
        a = int(hex_color[6:8], 16)
    except ValueError as exc:
        raise ValueError(f"Invalid hex digits in {hex_color}") from exc
    return (r, g, b, a)


def rgba_to_hex(rgba: tuple[int, int, int, int]) -> str:
    """
    Converts an RGBA tuple (0-255 each) to a hex color string.

    Args:
        rgba: RGBA values in range 0-255.

    Returns:

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Expand the color to 6-digit RGB or 8-digit RGBA form: '#FF00FF' or '#FF00FF80'.
  2. If you have 3-digit CSS shorthand, expand each nibble manually: '#F0A' -> '#FF00AA'.
  3. Validate color strings at startup with `sv.annotators.utils.is_valid_hex` before passing them to annotators.

Example fix

// before
sv.Color.from_hex("#FF0")  # 3-digit shorthand -> ValueError

// after
sv.Color.from_hex("#FFFF00")  # 6-digit RGB, alpha defaults to FF
Defensive patterns

Strategy: validation

Validate before calling

from supervision.annotators.utils import is_valid_hex

def safe_hex(h: str) -> str:
    h = h.strip().lstrip('#')
    if len(h) == 3:  # expand CSS shorthand
        h = ''.join(c * 2 for c in h)
    if not is_valid_hex('#' + h):
        raise ValueError(f"bad color: {h!r}")
    return '#' + h

Type guard

def is_valid_hex6_or_8(s: str) -> bool:
    s = s.strip().lstrip('#')
    return len(s) in (6, 8) and all(c in '0123456789abcdefABCDEF' for c in s)

Prevention

When it happens

Trigger: Calling `hex_to_rgba("#FF0")` (3-digit shorthand), `hex_to_rgba("FF00FF00FF")` (10 digits), `hex_to_rgba("")`, or `hex_to_rgba("#FF00F")` (5 digits). Also triggered indirectly by passing a malformed hex string to annotator constructors (e.g. `sv.Color.from_hex` or annotators that accept hex strings normalized via `_normalize_color_input`).

Common situations: Copying CSS 3-digit shorthand colors (#f00) from a stylesheet into annotator colors; typos or truncated color constants in config files; trailing characters after paste (e.g. '#FF00FF ' survives due to strip, but '#FF00FF0' does not); assuming 4-digit RGBA shorthand (#F00F) is supported like in CSS.

Related errors


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