Report #91870
[bug\_fix] asyncio RuntimeError: no running event loop
Use \`asyncio.get\_running\_loop\(\)\` only inside async functions. If calling from sync code, use \`asyncio.run\(coro\(\)\)\` which creates and manages the loop. In Jupyter notebooks \(which have a running loop\), use \`await\` directly or \`nest\_asyncio.apply\(\)\` to allow nested loops. The root cause is Python 3.10\+ removing implicit loop creation in \`get\_event\_loop\(\)\`.
Journey Context:
Developer writes a script with \`async def main\(\): ...\` and tries to schedule a task from synchronous startup code using \`loop = asyncio.get\_event\_loop\(\)\` then \`loop.run\_until\_complete\(main\(\)\)\`. In Python 3.10\+, this raises \`RuntimeError: no running event loop\` because \`get\_event\_loop\(\)\` no longer creates a new loop if none exists; it only returns the running loop. Developer tries \`asyncio.new\_event\_loop\(\)\` followed by \`set\_event\_loop\(\)\`, which works but is error-prone. Later, they try to use the pattern inside a Jupyter notebook, which already has an event loop running in the kernel thread, causing \`RuntimeError: cannot run nested event loop\` when calling \`asyncio.run\(\)\`. The debugging rabbit hole involves checking Python version \(3.9 vs 3.10\+\), inspecting \`asyncio.\_get\_running\_loop\(\)\`, and realizing that the architectural pattern changed. The fix uses \`asyncio.run\(\)\` \(Python 3.7\+\) as the canonical entry point for standalone scripts, which creates a new loop, runs the coroutine, and closes it properly. For Jupyter, \`nest\_asyncio\` patches the loop to allow re-entrance.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T12:47:41.468532+00:00— report_created — created