Textualize/rich · error · ColorParseError

{original_color!r} is not a valid color

Error message

{original_color!r} is not a valid color

What it means

Color.parse (via the Color classmethod used for every color string rich handles) raises ColorParseError when the string matches none of the accepted forms: a standard/eight-bit ANSI name (like "red" or "grey42"), a 6-digit hex like "#ffcc00", a bare number 0-255, or "rgb(r,g,b)". The regex RE_COLOR rejects the string after the ANSI name lookup fails. This propagates up through Style parsing, so a bad color inside a style string (e.g. "bold on nosuchcolor") surfaces as this error (often wrapped in StyleSyntaxError).

Source

Thrown at rich/color.py:451

    def parse(cls, color: str) -> "Color":
        """Parse a color definition."""
        original_color = color
        color = color.lower().strip()

        if color == "default":
            return cls(color, type=ColorType.DEFAULT)

        color_number = ANSI_COLOR_NAMES.get(color)
        if color_number is not None:
            return cls(
                color,
                type=(ColorType.STANDARD if color_number < 16 else ColorType.EIGHT_BIT),
                number=color_number,
            )

        color_match = RE_COLOR.match(color)
        if color_match is None:
            raise ColorParseError(f"{original_color!r} is not a valid color")

        color_24, color_8, color_rgb = color_match.groups()
        if color_24:
            triplet = ColorTriplet(
                int(color_24[0:2], 16), int(color_24[2:4], 16), int(color_24[4:6], 16)
            )
            return cls(color, ColorType.TRUECOLOR, triplet=triplet)

        elif color_8:
            number = int(color_8)
            if number > 255:
                raise ColorParseError(f"color number must be <= 255 in {color!r}")
            return cls(
                color,
                type=(ColorType.STANDARD if number < 16 else ColorType.EIGHT_BIT),
                number=number,
            )

View on GitHub (pinned to 9d8f9a372c)

Solutions

  1. Fix the color string: use a documented ANSI name (see rich.color.ANSI_COLOR_NAMES), "#rrggbb" hex, "rgb(r,g,b)", or an integer 0-255
  2. If the color comes from user/theme config, validate it once at load time with a try/except ColorParseError and fall back to a default
  3. Check for 3-digit CSS hex (#fc0) and expand it to 6 digits (#ffcc00) before passing to rich
  4. Upgrade rich if the color name is a newer addition (e.g. some greyNN names)

Example fix

// before (Python)
Color.parse("#fc0")            # ColorParseError
console.print("hi", style="on maganta")  # ColorParseError
// after
Color.parse("#ffcc00")
console.print("hi", style="on magenta")
Defensive patterns

Strategy: try-catch

Validate before calling

import re
from rich.color import ANSI_COLOR_NAMES, RE_COLOR

def looks_like_color(s: str) -> bool:
    return s in ANSI_COLOR_NAMES or RE_COLOR.match(s) is not None

Type guard

def is_probably_valid_color(value: str) -> bool:
    from rich.color import ANSI_COLOR_NAMES, RE_COLOR
    return value in ANSI_COLOR_NAMES or bool(RE_COLOR.match(value))

Try / catch

from rich.color import ColorParseError, Color

try:
    color = Color.parse(user_color)
except ColorParseError:
    color = Color.parse("default")  # fallback
    log.warning("unknown color %r, using default", user_color)

Prevention

When it happens

Trigger: console.print("x", style="bck #ff0000") with a typo'd color name; Color.parse("#ffcc0") (5 hex digits); Color.parse("rgb(300,0,0)") actually hits a different check, but "rgb(1 2 3)" or "blueish" hits this one; passing a color from unvalidated user/theme config.

Common situations: Typos in color names in theme files or CLI style flags ("maganta", "grean"); hex strings with missing digits or a missing '#' handled elsewhere; CSS-style 3-digit hex (#fc0) which rich does not support; theme JSON keys pointing at colors from a newer rich version (e.g. "grey37" variants) while running an older rich.

Related errors


AI-assisted analysis of Textualize/rich@9d8f9a372c (2026-08-15). Data as JSON: /api/errors/13849c9f9b4bfc77. Report an issue: GitHub.