Textualize/textual · error · ScreenError
Can't await screen.dismiss() from the screen's message handl
Error message
Can't await screen.dismiss() from the screen's message handler; try removing the await keyword.
What it means
Textual forbids awaiting screen.dismiss() from within that screen's own message handler because it would require the screen to wait for its own removal, deadlocking the message pump. The check runs in a pre-await callback.
Source
Thrown at src/textual/screen.py:2075
call `self.dismiss()` _without_ awaiting.
Args:
result: The optional result to be passed to the result callback.
"""
_rich_traceback_omit = True
if self._result_callbacks:
callback = self._result_callbacks[-1]
callback(result)
await_pop = self.app.pop_screen()
def pre_await() -> None:
"""Called by the AwaitComplete object."""
_rich_traceback_omit = True
if active_message_pump.get() is self:
from textual.app import ScreenError
raise ScreenError(
"Can't await screen.dismiss() from the screen's message handler; try removing the await keyword."
)
await_pop.set_pre_await_callback(pre_await)
return await_pop
def pop_until_active(self) -> None:
"""Pop any screens on top of this one, until this screen is active.
Raises:
ScreenError: If this screen is not in the current mode.
"""
from textual.app import ScreenError
try:
self.app._pop_to_screen(self)View on GitHub (pinned to 06dbeef4bb)
Solutions
- Remove the await: call self.dismiss(result) directly
- If you need post-dismiss logic, chain it via .call_after_refresh or a callback rather than awaiting dismissal
- Restructure so the caller awaits dismiss, not the screen itself
Example fix
# before
async def on_button_pressed(self, event) -> None:
await self.dismiss(event.button.id)
# after
def on_button_pressed(self, event) -> None:
self.dismiss(event.button.id) Defensive patterns
Strategy: validation
Prevention
- Never await self.dismiss() inside the screen's own handlers
- Chain post-dismiss work with call_later/worker callbacks
When it happens
Trigger: Writing 'await self.dismiss(result)' inside on_mount, event handlers, or actions of the same screen instance.
Common situations: Dialog screens trying 'await self.dismiss(...)' after a button press instead of the non-awaited form; code migrated from older Textual versions where this was tolerated.
Related errors
- Can't call worker.wait from within the worker function!
- Can not create a worker from a non-async function unless `th
- node has no screen
- unable to run callback {event.callback!r}; {error}
- Timed out while waiting for widgets to process pending messa
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/9383abc6d09823b4.
Report an issue: GitHub.