Report #14960
[bug\_fix] RuntimeError: Task got Future attached to a different loop
Move the initialization of async clients \(e.g., \`aiohttp.ClientSession\`\) inside the async function or lifespan context manager, rather than at module level. Objects bound to a specific event loop \(like sessions created via \`asyncio.get\_event\_loop\(\)\` at import time\) cannot be reused in a different loop created later by \`asyncio.run\(\)\` or a web server.
Journey Context:
You're building a FastAPI app. In \`db.py\`, you write \`client = AsyncIOMotorClient\(...\)\` at the top level. In \`main.py\`, you import \`db.client\` and use it in an endpoint. On the first request, you get \`RuntimeError: ... attached to a different loop\`. You restart, it works, then fails on reload. You created the client at import time, which captured the current event loop \(if any\) or created one. However, \`asyncio.run\(\)\` \(called by uvicorn/FastAPI\) creates a \*new\* loop in the main thread. The client object is bound to the old loop. When the request tries to use it, the coroutine is scheduled on the new loop, but the underlying connection is bound to the old loop.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T22:49:26.223064+00:00— report_created — created