Textualize/textual · error · StyleValueError

Invalid color value {color}

Error message

Invalid color value {color}

What it means

The else-branch of ColorProperty.__set__ fires when the assigned color is neither None, a Color instance, nor a str — i.e. an entirely wrong Python type such as int, tuple, or list. Unlike the token-level parse error (which handles bad strings), this rejects the value before any parsing because its type is unparseable.

Source

Thrown at src/textual/css/_style_properties.py:1027

                        alpha = percentage_string_to_float(token)
                    except ValueError:
                        raise StyleValueError(f"invalid percentage value '{token}'")
                    continue
                try:
                    parsed_color = Color.parse(token)
                except ColorParseError as error:
                    raise StyleValueError(
                        f"Invalid color value '{token}'",
                        help_text=color_property_help_text(
                            self.name, context="inline", error=error, value=token
                        ),
                    )
            parsed_color = parsed_color.multiply_alpha(alpha)

            if obj.set_rule(self.name, parsed_color):
                obj.refresh(children=True)
        else:
            raise StyleValueError(f"Invalid color value {color}")


class ScrollbarColorProperty(ColorProperty):
    """A descriptor to set scrollbar color(s)."""

    def __set__(self, obj: StylesBase, color: Color | str | None) -> None:
        super().__set__(obj, color)

        if obj.node is None:
            return

        from textual.widget import Widget

        if isinstance(obj.node, Widget):
            widget = obj.node

            if widget.show_horizontal_scrollbar:
                widget.horizontal_scrollbar.refresh()

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Convert tuples to `Color(r, g, b)` or a color string before assignment
  2. Add isinstance validation when style values come from external data

Example fix

# before
styles.color = (255, 0, 0)
# after
from rich.color import Color
styles.color = Color(255, 0, 0)
Defensive patterns

Strategy: type-guard

Validate before calling

from rich.color import Color
if color is None or isinstance(color, (str, Color)):
    styles.color = color

Type guard

def is_color_value(v) -> bool:
    return v is None or isinstance(v, (str, Color))

Prevention

When it happens

Trigger: `styles.color = (255, 0, 0)` (RGB tuple), `styles.color = 0xFF0000` (int), `styles.color = ["red"]` — anything that is not None, Color, or str.

Common situations: Porting code from GUI frameworks that accept tuples (Tkinter, pygame) or passing config-driven values without normalization to strings/Color objects.

Related errors


AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27). Data as JSON: /api/errors/55c67ccb3f4ecba3. Report an issue: GitHub.