Textualize/textual · error · InvalidThemeError
Theme {theme_name!r} has not been registered. Call 'App.regi
Error message
Theme {theme_name!r} has not been registered. Call 'App.register_theme' before setting the 'App.theme' attribute. What it means
InvalidThemeError raised by the theme reactive validator when setting App.theme to a name that is not in App.available_themes. Themes must be registered (built-in or via register_theme) before assignment.
Source
Thrown at src/textual/app.py:1500
A dictionary mapping theme names to Theme instances.
"""
return {**self._registered_themes}
@property
def current_theme(self) -> Theme:
theme = self.get_theme(self.theme)
if theme is None:
theme = self.get_theme("textual-dark")
assert theme is not None # validated by _validate_theme
return theme
def _validate_theme(self, theme_name: str) -> str:
if theme_name not in self.available_themes:
message = (
f"Theme {theme_name!r} has not been registered. "
"Call 'App.register_theme' before setting the 'App.theme' attribute."
)
raise InvalidThemeError(message)
return theme_name
def _watch_theme(self, theme_name: str) -> None:
"""Apply a theme to the application.
This method is called when the theme reactive attribute is set.
"""
theme = self.current_theme
dark = theme.dark
# Setting the theme adds class "-theme-<THEME NAME>" to the App
classes = {name: False for name in self.classes if name.startswith("-theme-")}
classes[f"-theme-{self.current_theme.name}"] = True
classes["-dark-mode"] = dark
classes["-light-mode"] = not dark
self.update_classes(classes, update=False)
self._refresh_truecolor_filter(self.ansi_theme)View on GitHub (pinned to 06dbeef4bb)
Solutions
- Register first: self.register_theme(Theme(name="my_custom", ...)) then self.theme = "my_custom"
- Check the name exists: assert name in self.available_themes before assigning
- For built-ins use exact names, e.g. "textual-dark", "gruvbox"
Example fix
# before self.theme = "nord" # not registered # after theme = Theme(name="nord", primary="#88C0D0") self.register_theme(theme) self.theme = "nord"
Defensive patterns
Strategy: validation
Validate before calling
if theme_name not in app.available_themes:
app.register_theme(Theme(name=theme_name, primary="#..."))
app.theme = theme_name Try / catch
try:
self.app.theme = name
except InvalidThemeError:
self.log.warning(f'theme {name} missing; keeping default') Prevention
- Register custom themes in on_mount before any theme assignment
- Source theme names from available_themes in settings UIs
When it happens
Trigger: self.theme = "my_custom" without having called self.register_theme(Theme(...)); misspelling a built-in theme name like 'tokyo-night'.
Common situations: Adding custom themes after app startup; upgrading Textual where built-in theme names changed; setting theme from a config file value.
Related errors
- {theme!r} is not a builtin theme, or it has not been registe
- Can't animate attribute {attribute!r} on {obj!r}; attribute
- Don't know how to animate {value!r}; Can only animate <int>,
- Can't encode {datum!r}
- must be bytes
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/955b9a47d784ef2c.
Report an issue: GitHub.