nextlevelbuilder/ui-ux-pro-max-skill · error · ValueError
invalid hex color '{value}'
Error message
invalid hex color '{value}' What it means
validate_data.py's WCAG contrast helper _relative_luminance() requires an opaque six-digit hex color (#RRGGBB). It fullmatch-es the value against HEX_COLOR (`#[0-9A-Fa-f]{6}`) before slicing channels at offsets 1/3/5; anything else — 3-digit shorthand, missing '#', named colors, 8-digit hex with alpha, empty string — raises this ValueError. It is called via contrast_ratio() on color CSV columns (validate_data.py:393).
Source
Thrown at src/ui-ux-pro-max/scripts/validate_data.py:150
"threejs": {"threejs.org", "github.com", "www.npmjs.com", "www.w3.org"},
"laravel": {"laravel.com"},
}
REQUIRED_UX_GUIDANCE = {
"Focus Not Obscured (Minimum)": "Web",
"Focus Not Obscured (Enhanced)": "Web",
"Focus Appearance": "Web",
"Dragging Movements": "All",
"Target Size (Minimum)": "Web",
"Consistent Help": "All",
"Redundant Entry": "All",
"Accessible Authentication (Minimum)": "All",
"Auto-Rotating Content Controls": "All",
}
def _relative_luminance(value):
if not HEX_COLOR.fullmatch(value or ""):
raise ValueError(f"invalid hex color '{value}'")
channels = [int(value[index:index + 2], 16) / 255 for index in (1, 3, 5)]
linear = [channel / 12.92 if channel <= 0.04045
else ((channel + 0.055) / 1.055) ** 2.4 for channel in channels]
return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2]
def contrast_ratio(foreground, background):
"""Return WCAG contrast for two opaque six-digit sRGB colors."""
first, second = _relative_luminance(foreground), _relative_luminance(background)
return (max(first, second) + 0.05) / (min(first, second) + 0.05)
def _read_rows(filepath):
with open(filepath, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
return reader.fieldnames or [], list(reader)
View on GitHub (pinned to a38d04c3d5)
Solutions
- Find the offending row: the error prints the bad value; grep the color CSVs for it (`rg "FFF'|white|rgba" src/ui-ux-pro-max/data/colors.csv`).
- Rewrite the value as full six-digit hex with the leading '#', e.g. '#FFFFFF' not '#FFF' or 'FFF'.
- Strip alpha information: '#FFFFFFFF' is invalid — use the 6-digit RGB form; the contrast model assumes opaque colors.
- Re-run `python3 src/ui-ux-pro-max/scripts/validate_data.py` to confirm all rows pass, then `npm run sync:assets` in cli/ to mirror the fix.
Example fix
# before (colors.csv) Dark Theme,Primary,#111,Background,#FFF # after (colors.csv) Dark Theme,Primary,#111111,Background,#FFFFFF
Defensive patterns
Strategy: validation
Validate before calling
import re
HEX_COLOR = re.compile(r"#[0-9A-Fa-f]{6}")
def is_opaque_hex(value):
return bool(value) and HEX_COLOR.fullmatch(value) is not None
# before calling contrast_ratio on CSV rows:
for fg, bg in pairs:
if not (is_opaque_hex(fg) and is_opaque_hex(bg)):
raise ValueError(f"row has non-6-digit-hex color: {fg!r}, {bg!r}") Type guard
def is_opaque_hex(value) -> bool:
return isinstance(value, str) and bool(re.fullmatch(r"#[0-9A-Fa-f]{6}", value)) Prevention
- Mandate #RRGGBB in contributing docs for all color columns; reject shorthand at review.
- Run validate_data.py after every colors.csv edit, before sync:assets.
- Design-tool exports: normalize 3-digit to 6-digit (#abc -> #aabbcc) in your ingestion script.
When it happens
Trigger: A colors.csv row has a Primary/Background/Text column containing e.g. 'FFF' (no #), '#FFF' (3-digit), 'rgba(...)' , 'white', an empty cell, or a value with trailing whitespace — contrast_ratio(row[foreground], row[background]) passes it straight to _relative_luminance and the fullmatch fails.
Common situations: Adding new palettes to colors.csv with hand-typed shorthand hex; copy-pasting colors from design tools that emit 3-digit or 8-digit hex; leaving a column blank for a palette variant.
Related errors
- Unterminated quoted CSV field
- Unknown or missing style status: ${status || "<empty>"}
- invalid {} action value: {}
- Unknown AI type: ${aiType}
- Invalid JSON file {path}: {error}
AI-assisted analysis of nextlevelbuilder/ui-ux-pro-max-skill@a38d04c3d5 (2026-08-14).
Data as JSON: /api/errors/e43ef150615a1730.
Report an issue: GitHub.