Textualize/textual · error · TypeError
add_mode() must be called with a Screen type, not an instanc
Error message
add_mode() must be called with a Screen type, not an instance (got instance of {type(base_screen).__name__}) What it means
TypeError raised by App.add_mode when base_screen is an instantiated Screen rather than a type/callable, mirroring the MODES validation: modes store screen factories.
Source
Thrown at src/textual/app.py:2693
return await_mount
def add_mode(self, mode: str, base_screen: str | Callable[[], Screen]) -> None:
"""Adds a mode and its corresponding base screen to the app.
Args:
mode: The new mode.
base_screen: The base screen associated with the given mode.
Raises:
InvalidModeError: If the name of the mode is not valid/duplicated.
"""
if mode == "_default":
raise InvalidModeError("Cannot use '_default' as a custom mode.")
elif mode in self._modes:
raise InvalidModeError(f"Duplicated mode name {mode!r}.")
if isinstance(base_screen, Screen):
raise TypeError(
"add_mode() must be called with a Screen type, not an instance"
f" (got instance of {type(base_screen).__name__})"
)
self._modes[mode] = base_screen
def remove_mode(self, mode: str) -> AwaitComplete:
"""Removes a mode from the app.
Screens that are running in the stack of that mode are scheduled for pruning.
Args:
mode: The mode to remove. It can't be the active mode.
Raises:
ActiveModeError: If trying to remove the active mode.
UnknownModeError: If trying to remove an unknown mode.
"""
if mode == self._current_mode:View on GitHub (pinned to 06dbeef4bb)
Solutions
- Pass the class: await app.add_mode("editor", EditorScreen)
- Pass a factory lambda if construction args are needed: lambda: EditorScreen(item)
Example fix
# before
await app.add_mode("editor", EditorScreen())
# after
await app.add_mode("editor", EditorScreen) Defensive patterns
Strategy: type-guard
Validate before calling
assert not isinstance(base_screen, Screen), 'pass the Screen class'
Type guard
def is_screen_factory(v) -> bool:
return isinstance(v, str) or (callable(v) and not isinstance(v, Screen)) Prevention
- Never add () when passing screens to add_mode
- Use lambda: Screen(args) for parameterized screens
When it happens
Trigger: await app.add_mode("editor", EditorScreen()) — note the parentheses creating an instance.
Common situations: Easy slip of adding () when typing the call; passing a pre-built screen to share state.
Related errors
- expected a callable or string, got {screen_object!r}
- MODES cannot contain instances, use a type instead (got inst
- {variable_name} should contain a Screen type or callable, no
- No mode called {mode!r}
- No known mode {self._current_mode!r}
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/f9fcf700311d7608.
Report an issue: GitHub.