Textualize/textual · error · RuntimeError
App is not running
Error message
App is not running
What it means
RuntimeError raised by App.call_from_thread when self._loop is None, i.e. the app's asyncio event loop is not (yet/anymore) running. The method marshals a callback onto that loop, so it cannot work without it.
Source
Thrown at src/textual/app.py:1819
!!! tip
Consider using [post_message][textual.message_pump.MessagePump.post_message] which is also thread-safe.
Args:
callback: A callable to run.
*args: Arguments to the callback.
**kwargs: Keyword arguments for the callback.
Raises:
RuntimeError: If the app isn't running or if this method is called from the same
thread where the app is running.
Returns:
The result of the callback.
"""
if self._loop is None:
raise RuntimeError("App is not running")
if self._thread_id == threading.get_ident():
raise RuntimeError(
"The `call_from_thread` method must run in a different thread from the app"
)
callback_with_args = partial(callback, *args, **kwargs)
async def run_callback() -> CallThreadReturnType:
"""Run the callback, set the result or error on the future."""
with self._context():
return await invoke(callback_with_args)
# Post the message to the main loop
future: Future[CallThreadReturnType] = asyncio.run_coroutine_threadsafe(
run_callback(), loop=self._loop
)
result = future.result()View on GitHub (pinned to 06dbeef4bb)
Solutions
- Only call call_from_thread once the app is running (from on_mount onward)
- Check app._loop / app.is_running before calling, or defer with a small retry/queue
- Cancel/suppress late callbacks on shutdown (e.g. check a shutdown flag in the thread)
Example fix
# before
def worker():
app.call_from_thread(update_ui) # may run before loop starts
# after
async def on_mount(self):
self.run_worker(worker, thread=True)
def worker():
if self.app._loop is not None:
self.app.call_from_thread(update_ui) Defensive patterns
Strategy: validation
Validate before calling
if app._loop is not None and app.is_running:
app.call_from_thread(cb)
else:
queue_or_skip() Try / catch
try:
app.call_from_thread(cb)
except RuntimeError:
pass # app shutting down; drop update Prevention
- Spawn thread workers only from on_mount onward
- Check is_running before posting from threads
- Drop stale updates on shutdown
When it happens
Trigger: Calling call_from_thread from a worker thread before the app finished starting (before on_mount/run), or after the app has shut down; also when called outside run_async/run_terse lifecycle.
Common situations: Thread workers spawned at __init__ time firing before the loop is set; callbacks arriving after user exit; tests driving methods without running the app.
Related errors
- The `call_from_thread` method must run in a different thread
- Can't remove active mode {mode!r}
- node has no screen
- There is no active worker in this task or thread.
- Worker must be started before calling this method.
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/e330caa4c023b9ca.
Report an issue: GitHub.