Textualize/rich · error · ValueError

expected at least one non-None style

Error message

expected at least one non-None style

What it means

Style.pick_first(*values) is a classmethod convenience that returns the first non-None argument, letting callers express 'use A, else B'. If every argument is None there is nothing to return, so it raises ValueError('expected at least one non-None style'). It is strict: empty call or all-None raises rather than returning a default.

Source

Thrown at rich/style.py:410

        Args:
            style (str): A style definition.

        Returns:
            str: Normal form of style definition.
        """
        try:
            return str(cls.parse(style))
        except errors.StyleSyntaxError:
            return style.strip().lower()

    @classmethod
    def pick_first(cls, *values: Optional[StyleType]) -> StyleType:
        """Pick first non-None style."""
        for value in values:
            if value is not None:
                return value
        raise ValueError("expected at least one non-None style")

    def __rich_repr__(self) -> Result:
        yield "color", self.color, None
        yield "bgcolor", self.bgcolor, None
        yield "bold", self.bold, None,
        yield "dim", self.dim, None,
        yield "italic", self.italic, None
        yield "underline", self.underline, None,
        yield "blink", self.blink, None
        yield "blink2", self.blink2, None
        yield "reverse", self.reverse, None
        yield "conceal", self.conceal, None
        yield "strike", self.strike, None
        yield "underline2", self.underline2, None
        yield "frame", self.frame, None
        yield "encircle", self.encircle, None
        yield "link", self.link, None
        if self._meta:

View on GitHub (pinned to 9d8f9a372c)

Solutions

  1. Append an explicit fallback as the last argument: Style.pick_first(user_style, theme_style, Style.parse('')).
  2. Guard the call: if any(v is not None for v in values): ... else use your default.
  3. Rearchitect optional styles as a single Optional[StyleType] chosen with a plain 'or'-chain with a concrete default, avoiding pick_first for the always-present case.

Example fix

# before
style = Style.pick_first(cfg_style, theme_style)  # both None -> ValueError

# after
style = Style.pick_first(cfg_style, theme_style, 'none')  # last-resort default
Defensive patterns

Strategy: fallback

Validate before calling

values = [v for v in (a, b, c) if v is not None]
if not values:
    raise ValueError('no style sources available')
style = Style.pick_first(a, b, c) if values else 'none'

Type guard

def has_any_style(*values) -> bool:
    return any(v is not None for v in values)

Prevention

When it happens

Trigger: Style.pick_first(None, None); Style.pick_first(*styles) where styles is an empty or all-None list; using it to merge optional style overrides (e.g. Style.pick_first(user_style, theme_style, base_style)) when all three sources are None.

Common situations: Layered theming/config systems where every optional style layer is absent; passing **kwargs through several levels where the style key was never set; calling pick_first() with no arguments at all.

Related errors


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