roboflow/supervision · error · AttributeError

module {__name__} has no attribute {name}

Error message

module {__name__} has no attribute {name}

What it means

Thrown by supervision's internal _validate_color_hex helper when a hex color string, after stripping a leading '#', contains valid hex characters but its length is not 3, 4, 6, or 8. The library only supports CSS-style shorthand (RGB, RGBA), 6-digit RRGGBB, and 8-digit RRGGBBAA forms. Any other length (e.g. 5 or 7 characters) is rejected before Color.from_hex can parse it.

Source

Thrown at src/supervision/__init__.py:317

    "tint_image",
    "xcycwh_to_xyxy",
    "xywh_to_xyxy",
    "xyxy_to_mask",
    "xyxy_to_polygons",
    "xyxy_to_xcycarh",
    "xyxy_to_xywh",
    "xyxyxyxy_to_xyxy",
]


def __getattr__(name: str) -> Any:
    """Lazily resolve deprecated compatibility exports."""
    if name == "ByteTrack":
        from supervision.tracker.byte_tracker.core import ByteTrack as byte_track

        globals()[name] = byte_track
        return byte_track
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Check the length of the hex string after removing '#': it must be exactly 3, 4, 6, or 8 characters, then fix the typo (most cases are a truncated or extra digit).
  2. If you intended shorthand with alpha, use 4 digits (#RGBA) or the explicit 8-digit form #RRGGBBAA.
  3. If generating hex programmatically, format with fixed width, e.g. f'#{value:06X}', and pad instead of truncating.
  4. Wrap user-supplied colors in a small sanitizer that validates with a regex like ^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$ before passing them to supervision.

Example fix

# before
sv.Color.from_hex('#FF000')  # 5 digits -> ValueError: Invalid length of color hash

# after
sv.Color.from_hex('#FF0000')  # 6-digit RRGGBB
sv.Color.from_hex('#FF000080')  # 8-digit RRGGBBAA with alpha
Defensive patterns

Strategy: validation

Validate before calling

import re

_HEX_RE = re.compile(r"^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$")

def is_valid_color_hex(s: str) -> bool:
    """True if supervision's Color.from_hex will accept the string."""
    return bool(_HEX_RE.match(s))

# before: sv.ColorPalette.from_hex(user_colors)
# after:
# assert all(is_valid_color_hex(c) for c in user_colors), user_colors

Type guard

def is_valid_color_hex(s: str) -> bool:
    """Narrow a str to one Color.from_hex accepts (3/4/6/8 hex digits)."""
    return bool(re.match(r"^#?[0-9a-fA-F]{3,8}$", s)) and len(s.lstrip('#')) in (3, 4, 6, 8)

Try / catch

try:
    color = sv.Color.from_hex(hex_str)
except ValueError as e:
    if 'color hash' in str(e):
        logger.warning("dropping malformed color %r: %s", hex_str, e)
        color = sv.Color.DEFAULT
    else:
        raise

Prevention

When it happens

Trigger: Calling sv.Color.from_hex('#FF000') (5 digits, a typo), sv.Color.from_hex('8000') expecting an 8-digit alpha color, passing sv.ColorPalette.from_hex(['#12345']) with a truncated hex, or building a palette from user/theme-supplied colors that use non-standard lengths like 12-digit hex.

Common situations: Typos in config files or UI color pickers feeding hex strings into annotator color arguments; copying colors from design tools that emit formats like '#RGBAA' variants or hex with alpha in unusual positions; converting numeric colors to hex with wrong padding (e.g. hex(255) -> 'ff' concatenated incorrectly producing odd lengths).

Related errors


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