Textualize/rich · error · KeyError

no spinner called {name!r}

Error message

no spinner called {name!r}

What it means

Spinner(name) looks up the name in rich's bundled SPINNERS dictionary (from _spinners.json, pygments-style spinner definitions). An unknown key raises KeyError('no spinner called {name!r}') at construction — raised explicitly instead of letting the raw KeyError escape so the message is actionable.

Source

Thrown at rich/spinner.py:37

        style (StyleType, optional): Style for spinner animation. Defaults to None.
        speed (float, optional): Speed factor for animation. Defaults to 1.0.

    Raises:
        KeyError: If name isn't one of the supported spinner animations.
    """

    def __init__(
        self,
        name: str,
        text: "RenderableType" = "",
        *,
        style: Optional["StyleType"] = None,
        speed: float = 1.0,
    ) -> None:
        try:
            spinner = SPINNERS[name]
        except KeyError:
            raise KeyError(f"no spinner called {name!r}")
        self.text: "Union[RenderableType, Text]" = (
            Text.from_markup(text) if isinstance(text, str) else text
        )
        self.name = name
        self.frames = cast(List[str], spinner["frames"])[:]
        self.interval = cast(float, spinner["interval"])
        self.start_time: Optional[float] = None
        self.style = style
        self.speed = speed
        self.frame_no_offset: float = 0.0
        self._update_speed = 0.0

    def __rich_console__(
        self, console: "Console", options: "ConsoleOptions"
    ) -> "RenderResult":
        yield self.render(console.get_time())

    def __rich_measure__(

View on GitHub (pinned to 9d8f9a372c)

Solutions

  1. Print the available names to pick a valid one: from rich._spinners import SPINNERS; print(sorted(SPINNERS)).
  2. Fix the name/casing (e.g. 'dots', 'bouncingBar').
  3. Validate user-supplied names: Spinner(name if name in SPINNERS else 'dots').

Example fix

# before
sp = Spinner('Dots')  # KeyError: no spinner called 'Dots'

# after
from rich._spinners import SPINNERS
sp = Spinner(name if name in SPINNERS else 'dots')
Defensive patterns

Strategy: validation

Validate before calling

from rich._spinners import SPINNERS
name = name if name in SPINNERS else 'dots'
spinner = Spinner(name, 'working...')

Type guard

def is_known_spinner(name: str) -> bool:
    from rich._spinners import SPINNERS
    return isinstance(name, str) and name in SPINNERS

Try / catch

try:
    sp = Spinner(name)
except KeyError as e:
    from rich._spinners import SPINNERS
    sp = Spinner('dots')  # log available: sorted(SPINNERS)

Prevention

When it happens

Trigger: Spinner('dots2 ') with trailing whitespace, Spinner('Dots') with wrong casing, Spinner('my-custom') which does not exist in the bundled set, or a name that changed between rich versions. Valid examples include 'dots', 'line', 'circle', 'arrow', 'bouncingBar', 'aesthetic'.

Common situations: Hardcoding a spinner name copied from another library (cli-spinners JS names mostly match but not always); typos/casing errors; upgrading rich where spinner names were added/renamed; user-configurable spinner names from CLI flags.

Related errors


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