Skip to content
Latchkey

FastAPI "RuntimeError: There is no current event loop" in CI

An async test or fixture called asyncio.get_event_loop() when no loop was running. On recent Python versions that no longer auto-creates a loop, and without pytest-asyncio driving the test, the coroutine has nothing to run on.

What this error means

An async FastAPI test fails with "RuntimeError: There is no current event loop in thread 'MainThread'" or a coroutine "was never awaited" warning and no assertions run.

python
RuntimeError: There is no current event loop in thread 'MainThread'.

  loop = asyncio.get_event_loop()

Common causes

pytest-asyncio is not driving the async test

Without pytest-asyncio (and its mode), an async def test is collected but never awaited, so loop-dependent code fails.

get_event_loop with no running loop on newer Python

Recent Python deprecated auto-creating a loop in get_event_loop(), so code that assumed one exists now raises.

How to fix it

Install and enable pytest-asyncio

  1. Install pytest-asyncio in the test environment.
  2. Set an asyncio mode so async tests are awaited.
  3. Use an async client such as httpx.AsyncClient with the app.
tests/test_api.py
import pytest, httpx
from app.main import app

@pytest.mark.asyncio
async def test_health():
    transport = httpx.ASGITransport(app=app)
    async with httpx.AsyncClient(transport=transport, base_url="http://test") as ac:
        r = await ac.get("/health")
    assert r.status_code == 200

Get the running loop instead of a current one

Inside async code, use asyncio.get_running_loop() rather than get_event_loop().

app/tasks.py
import asyncio
loop = asyncio.get_running_loop()

How to prevent it

  • Drive async tests with pytest-asyncio and an explicit mode.
  • Use get_running_loop() inside coroutines.
  • Prefer async clients for async endpoints instead of manual loops.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →