Textualize/textual · error · InvalidModeError

Cannot use '_default' as a custom mode.

Error message

Cannot use '_default' as a custom mode.

What it means

InvalidModeError raised by App.add_mode when the mode name is the reserved string "_default". Textual uses "_default" internally for the initial screen stack and it cannot be overridden.

Source

Thrown at src/textual/app.py:2688

        self.screen.post_message(events.ScreenResume())

        self.log.system(f"{self._current_mode!r} is the current mode")
        self.log.system(f"{self.screen} is active")

        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.

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Choose any other mode name, e.g. "main" or "home"
  2. Filter/alias the reserved name when generating modes dynamically

Example fix

# before
await app.add_mode("_default", HomeScreen)

# after
await app.add_mode("home", HomeScreen)
Defensive patterns

Strategy: validation

Validate before calling

assert mode != '_default', "'_default' is reserved"

Prevention

When it happens

Trigger: await app.add_mode("_default", MyScreen) or MODES containing a "_default" key.

Common situations: Generic code that programmatically registers modes from a list that includes a default entry.

Related errors


AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27). Data as JSON: /api/errors/80b6bb06fce09f3e. Report an issue: GitHub.