Quick reference for the recurring FastAPI errors you’ll see and the fix.
422 on what looks like valid input
Cause: parameter declared without Body() is treated as query param.
# Wrong
@app.post("/x")
async def x(name: str): ... # name is QUERY (not body)
# Right
@app.post("/x")
async def x(name: str = Body(...)): ...
# Or use a Pydantic model.
“RuntimeError: dictionary changed size during iteration” in tests
Cause: not clearing dependency_overrides between tests.
@pytest.fixture
def client():
app.dependency_overrides[get_db] = fake_db
yield TestClient(app)
app.dependency_overrides.clear() # always
CORS not working / preflight 400
Cause: CORS middleware order, or allow_credentials=True with allow_origins=["*"].
app.add_middleware(
CORSMiddleware,
allow_origins=["https://yourdomain.com"], # not ["*"] when credentials=True
allow_credentials=True,
allow_methods=["*"], allow_headers=["*"],
)
CORS must be added LAST among middleware so it runs FIRST.
TypeError: object dict can’t be used in ‘await’
Cause: missing async somewhere.
# Wrong
def get_db(): return AsyncSession(...)
@app.get("/")
async def home(db = Depends(get_db)):
await db.execute(...) # error: AsyncSession not awaited
Use a yield-style async dep:
async def get_db():
async with AsyncSessionLocal() as session:
yield session
“MissingGreenlet” / SQLAlchemy async errors
Cause: lazy-loading a relationship in async context.
# Wrong
user = await session.scalar(select(User).where(...))
print(user.posts) # implicit lazy load -> error
# Right
stmt = select(User).options(selectinload(User.posts)).where(...)
user = await session.scalar(stmt)
Or use await user.awaitable_attrs.posts.
“InvalidRequestError: This Session was already attached to a transaction”
Cause: nested session.begin() without begin_nested.
async with session.begin():
async with session.begin_nested(): # savepoint
...
Or use a single transaction.
Body always None
Cause: missing python-multipart for forms, missing Content-Type header.
uv add python-multipart
Client must send Content-Type: application/x-www-form-urlencoded (or multipart/form-data for files).
Pydantic v1 vs v2 confusion
# v1 (legacy)
.dict(), .json(), .parse_obj(...)
# v2 (current)
.model_dump(), .model_dump_json(), .model_validate(...)
If using pydantic v1: upgrade. v1 is in maintenance.
OpenAPI shows wrong response shape
Cause: missing response_model.
@app.get("/users/{id}", response_model=UserOut) # ALWAYS set this
response_model_exclude not respected
Cause: returning JSONResponse(...) directly bypasses response_model.
# Wrong
return JSONResponse(user.dict())
# Right
return user # FastAPI applies response_model
“Form data requires python-multipart”
uv add python-multipart
Long-running endpoint blocking other requests
Cause: synchronous code in async handler.
# Wrong
@app.get("/slow")
async def slow():
time.sleep(5) # blocks event loop
# Right
async def slow():
await asyncio.sleep(5)
# Or
async def slow():
await asyncio.to_thread(legacy_blocking_fn)
Stuck connections after prod restart
Cause: missing pool_pre_ping.
engine = create_async_engine(URL, pool_pre_ping=True, pool_recycle=300)
“Multiple heads detected” in Alembic
Cause: parallel migrations.
alembic heads # lists heads
alembic merge -m "merge X+Y" <head1> <head2>
See Alembic Textbook Ch 4 .
Pydantic alias not accepted on input
class M(BaseModel):
full_name: str = Field(alias="fullName")
model_config = {"populate_by_name": True} # accept BOTH
OAuth2 token endpoint expects form data
/token must accept application/x-www-form-urlencoded. The Swagger Authorize button sends form-encoded; if your endpoint takes JSON it won’t fit OAuth2 standards.
ImportError: cannot import name ‘AsyncSession’
from sqlalchemy.ext.asyncio import AsyncSession # not from sqlalchemy
MissingError on session.begin_nested() in async
async with session.begin():
async with session.begin_nested() as sp:
...
begin_nested() requires an outer transaction.
502 / 504 in production
Common causes:
- Worker died (OOM): check memory limits.
- Long request exceeded LB timeout: tune.
- Lifespan hung: don’t await indefinitely in startup.
Read this next
If you want my FastAPI debug runbook, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .