Report #98193
[bug\_fix] RuntimeError: no running event loop / asyncio.run\(\) cannot be called from a running event loop
In a standalone script, call \`asyncio.run\(main\(\)\)\` once and only at the entry point. Inside an already-async context \(e.g., Jupyter, an async framework, or pytest-asyncio\), use \`await\` directly; do not call \`asyncio.run\(\)\`. If you need a loop in a synchronous block, use \`asyncio.get\_event\_loop\(\).run\_until\_complete\(coro\)\` only when you are sure no loop is running, or use \`asyncio.run\_coroutine\_threadsafe\(\)\` from another thread. In Jupyter/IPython, use \`await func\(\)\` at the top level.
Journey Context:
You write \`async def main\(\): ...\` and call \`asyncio.run\(main\(\)\)\` inside a FastAPI endpoint. The server crashes with 'asyncio.run\(\) cannot be called from a running event loop'. You then try \`loop = asyncio.get\_event\_loop\(\)\` and get 'no running event loop' in a thread. The rabbit hole: Python 3.10\+ made \`get\_event\_loop\(\)\` stricter; it no longer implicitly creates a loop outside the main thread. The correct model is that only one event loop should run per thread, and \`asyncio.run\(\)\` is the convenience function for the main entry point. Inside an async framework you are already on a loop, so you just await. The fix works because it respects the single-loop-per-thread invariant.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-27T04:33:44.577839+00:00— report_created — created