{"record":{"id":"c77f1b1d21bf7b3d","repo":"nautechsystems/nautilus_trader","slug":"theme-name-not-found-suggestion-text-availab","errorCode":null,"errorMessage":"Theme '{name}' not found.{suggestion_text} Available themes: {available}. Register custom themes with register_theme().","messagePattern":"Theme '(.+?)' not found\\.(.+?) Available themes: (.+?)\\. Register custom themes with register_theme\\(\\)\\.","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"python/nautilus_trader/analysis/themes.py","lineNumber":122,"sourceCode":"    -------\n    dict[str, Any]\n        Theme configuration dictionary with \"template\" and \"colors\" keys.\n\n    Raises\n    ------\n    KeyError\n        If the theme name is not registered.\n\n    \"\"\"\n    _require_not_none(name, \"name\")\n\n    if name not in _THEMES:\n        available = \", \".join(_THEMES.keys())\n\n        suggestions = get_close_matches(name, _THEMES.keys(), n=3, cutoff=0.6)\n        suggestion_text = f\" Did you mean: {', '.join(suggestions)}?\" if suggestions else \"\"\n\n        raise KeyError(\n            f\"Theme '{name}' not found.{suggestion_text} \"\n            f\"Available themes: {available}. \"\n            f\"Register custom themes with register_theme().\",\n        )\n\n    theme = _THEMES[name].copy()\n    theme[\"colors\"] = theme[\"colors\"].copy()\n    return theme\n\n\ndef register_theme(name: str, template: str, colors: dict[str, str]) -> None:\n    \"\"\"\n    Register a custom theme.\n\n    Parameters\n    ----------\n    name : str\n        The theme name for future reference.","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/python/nautilus_trader/analysis/themes.py#L104-L140","documentation":"get_theme raises KeyError when the requested theme name is not in the _THEMES registry. Like the chart registry, it appends difflib close-match suggestions (cutoff 0.6) and the full available list; custom themes exist only after register_theme in the same process. This is the error surfaced when TearsheetConfig.theme names an unknown theme.","triggerScenarios":"get_theme('dark') (intended 'nautilus_dark'); TearsheetConfig(theme='plotly-black') typo; referencing a theme registered in a different run/process; theme names are case-sensitive, so 'Plotly_White' also fails.","commonSituations":"Hand-written theme strings in configs; themes renamed between nautilus_trader versions; assuming a custom theme registered in a notebook session persists to a fresh process.","solutions":["Use the suggestion hint or pick from the Available list in the message","List valid names: from nautilus_trader.analysis.themes import list_themes; print(list_themes())","For custom themes, call register_theme(name, template, colors) at startup before any get_theme/config use","Match casing exactly (built-ins are lowercase)"],"exampleFix":"# before\nget_theme('nautilusdrak')\n# KeyError: Theme 'nautilusdrak' not found. Did you mean: nautilus_dark? ...\n\n# after\nget_theme('nautilus_dark')","handlingStrategy":"validation","validationCode":"from nautilus_trader.analysis.themes import list_themes\n\nif theme not in list_themes():\n    raise ValueError(f'Unknown theme {theme!r}; choose from {list_themes()}')\nget_theme(theme)","typeGuard":"from nautilus_trader.analysis.themes import list_themes\n\ndef is_registered_theme(name: object) -> bool:\n    return isinstance(name, str) and name in list_themes()","tryCatchPattern":"try:\n    theme = get_theme(requested)\nexcept KeyError as e:\n    # fallback to a built-in instead of failing the whole render\n    logger.warning('%s; falling back to plotly_white', e)\n    theme = get_theme('plotly_white')","preventionTips":["Call register_theme for custom themes once at process startup","Treat theme names as case-sensitive constants defined near your config","Cover theme resolution in a startup self-check: assert get_theme(cfg.theme)"],"tags":["python","themes","registry-lookup","typo","keyerror","did-you-mean"],"backgroundTag":"unregistered-key-lookup","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}