{"record":{"id":"d770d4cd92eb3906","repo":"Textualize/rich","slug":"no-spinner-called-name-r","errorCode":null,"errorMessage":"no spinner called {name!r}","messagePattern":"no spinner called (.+?)","errorType":"validation","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"rich/spinner.py","lineNumber":37,"sourceCode":"        style (StyleType, optional): Style for spinner animation. Defaults to None.\n        speed (float, optional): Speed factor for animation. Defaults to 1.0.\n\n    Raises:\n        KeyError: If name isn't one of the supported spinner animations.\n    \"\"\"\n\n    def __init__(\n        self,\n        name: str,\n        text: \"RenderableType\" = \"\",\n        *,\n        style: Optional[\"StyleType\"] = None,\n        speed: float = 1.0,\n    ) -> None:\n        try:\n            spinner = SPINNERS[name]\n        except KeyError:\n            raise KeyError(f\"no spinner called {name!r}\")\n        self.text: \"Union[RenderableType, Text]\" = (\n            Text.from_markup(text) if isinstance(text, str) else text\n        )\n        self.name = name\n        self.frames = cast(List[str], spinner[\"frames\"])[:]\n        self.interval = cast(float, spinner[\"interval\"])\n        self.start_time: Optional[float] = None\n        self.style = style\n        self.speed = speed\n        self.frame_no_offset: float = 0.0\n        self._update_speed = 0.0\n\n    def __rich_console__(\n        self, console: \"Console\", options: \"ConsoleOptions\"\n    ) -> \"RenderResult\":\n        yield self.render(console.get_time())\n\n    def __rich_measure__(","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/Textualize/rich/blob/9d8f9a372cc5916fd4781fec207ced7ddac2f08f/rich/spinner.py#L19-L55","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Print the available names to pick a valid one: from rich._spinners import SPINNERS; print(sorted(SPINNERS)).","Fix the name/casing (e.g. 'dots', 'bouncingBar').","Validate user-supplied names: Spinner(name if name in SPINNERS else 'dots')."],"exampleFix":"# before\nsp = Spinner('Dots')  # KeyError: no spinner called 'Dots'\n\n# after\nfrom rich._spinners import SPINNERS\nsp = Spinner(name if name in SPINNERS else 'dots')","handlingStrategy":"validation","validationCode":"from rich._spinners import SPINNERS\nname = name if name in SPINNERS else 'dots'\nspinner = Spinner(name, 'working...')","typeGuard":"def is_known_spinner(name: str) -> bool:\n    from rich._spinners import SPINNERS\n    return isinstance(name, str) and name in SPINNERS","tryCatchPattern":"try:\n    sp = Spinner(name)\nexcept KeyError as e:\n    from rich._spinners import SPINNERS\n    sp = Spinner('dots')  # log available: sorted(SPINNERS)","preventionTips":["Validate spinner names against rich._spinners.SPINNERS when they come from config/CLI.","Names are case-sensitive; copy them exactly ('bouncingBar', 'dots').","After upgrading rich, re-verify hardcoded spinner names still exist."],"tags":["rich","spinner","lookup","keyerror","name-validation"],"backgroundTag":null,"analyzedSha":"9d8f9a372cc5916fd4781fec207ced7ddac2f08f","analyzedAt":"2026-08-15T03:30:11.781Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}