FastAPI "greenlet_spawn has not been called" (async SQLAlchemy) in CI
Async SQLAlchemy runs blocking DBAPI work inside a greenlet. When IO is triggered outside that context, usually a lazy-loaded relationship accessed after the session closed, it raises MissingGreenlet. Tests surface this when serializing ORM objects to a response model.
What this error means
A test fails with "sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here" while building a response from an ORM object.
sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call
await_only() here. Was IO attempted in an unexpected place?Common causes
Lazy loading a relationship outside the session
A response model reads a related attribute that was not loaded; the lazy load triggers IO after the async context ended.
greenlet is not installed for the async engine
The async engine needs the greenlet package; a slim install without it cannot run the async DBAPI bridge.
How to fix it
Eager-load relationships you serialize
Load related data inside the async query so no lazy IO happens during serialization.
from sqlalchemy.orm import selectinload
from sqlalchemy import select
stmt = select(Order).options(selectinload(Order.items))
orders = (await session.execute(stmt)).scalars().all()Ensure greenlet is installed
Install greenlet so the async engine has its execution bridge (SQLAlchemy async extras pull it in).
python -m pip install "sqlalchemy[asyncio]" greenletHow to prevent it
- Eager-load with selectinload/joinedload for data you serialize.
- Install
sqlalchemy[asyncio]so greenlet is present. - Keep ORM access inside the async session scope.