Textualize/textual · error · ScreenStackError

No screens on stack

Error message

No screens on stack

What it means

ScreenStackError raised by App.screen when the current mode's screen stack is empty (IndexError on _screen_stack[-1]). Every mode should always keep at least one screen; an empty stack means screens were popped without replacement.

Source

Thrown at src/textual/app.py:1641

        """The animator object."""
        return self._animator

    @property
    def screen(self) -> Screen[object]:
        """The current active screen.

        Returns:
            The currently active (visible) screen.

        Raises:
            ScreenStackError: If there are no screens on the stack.
        """
        try:
            return self._screen_stack[-1]
        except KeyError:
            raise UnknownModeError(f"No known mode {self._current_mode!r}") from None
        except IndexError:
            raise ScreenStackError("No screens on stack") from None

    @property
    def _background_screens(self) -> list[Screen]:
        """A list of screens that may be visible due to background opacity (top-most first, not including current screen)."""
        screens: list[Screen] = []
        for screen in reversed(self._screen_stack[:-1]):
            screens.append(screen)
            if screen.styles.background.a == 1:
                break
        background_screens = screens[::-1]
        return background_screens

    @property
    def size(self) -> Size:
        """The size of the terminal.

        Returns:
            Size of the terminal.

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Guard pops: if len(app.screen_stack) > 1: app.pop_screen()
  2. Use app.exit() instead of popping the last screen when ending the app
  3. Prefer switch_screen for replacing rather than push+pop patterns

Example fix

# before
if len(self.app.screen_stack) == 1:
    self.app.pop_screen()  # empties stack

# after
if len(self.app.screen_stack) == 1:
    self.app.exit()
else:
    self.app.pop_screen()
Defensive patterns

Strategy: validation

Validate before calling

def can_pop(app) -> bool:
    return len(app.screen_stack) > 1

Try / catch

try:
    app.pop_screen()
except ScreenStackError:
    app.exit()

Prevention

When it happens

Trigger: Calling pop_screen() on a stack with one screen in a mode where guards were bypassed, or accessing app.screen during teardown after the last screen was removed.

Common situations: Exit paths that pop the root screen; race between screen unmount and mode switching.

Related errors


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