Pydantic ValidationError: 'Field Required' and How to Read It
Pydantic's ValidationError looks noisy but it's the most helpful error you'll get — it lists every field that failed and why. Learn to read it once and you'll fix these in seconds.
You construct a model and Pydantic refuses:
pydantic_core._pydantic_core.ValidationError: 1 validation error for User
email
Field required [type=missing, input_value={'name': 'Ada'}, input_type=dict]
A ValidationError means the data you passed didn't satisfy the model's schema. Unlike most exceptions, this one is a report: it tells you the model (User), the field (email), the reason (Field required), and what you actually passed ({'name': 'Ada'}). Read those four things and the fix is obvious.
'Field required' means a mandatory field is missing
In Pydantic v2, a field with no default is required:
from pydantic import BaseModel
class User(BaseModel):
name: str
email: str # required
User(name="Ada") # ❌ ValidationError: email Field required
Two fixes, depending on intent:
email: str | None = None # optional, defaults to None
# or
email: str = "[email protected]" # optional, with a real default
If the field should be required, then the bug is upstream — you're not passing email when you build the model. Trace where the dict comes from.
Type errors: 'Input should be a valid integer'
age
Input should be a valid integer [type=int_parsing, input_value='twenty']
The value can't be coerced to the declared type. Pydantic will turn "25" into 25, but not "twenty". Either send a real number or change the field type to accept what you're actually giving it.
Read all the errors at once
Pydantic validates every field and reports them together — "3 validation errors for User" means three separate problems. Don't fix one and re-run three times. To handle them in code, catch the error and inspect .errors():
from pydantic import ValidationError
try:
User(**payload)
except ValidationError as e:
for err in e.errors():
print(err["loc"], err["msg"]) # ('email',) 'Field required'
.errors() gives you a clean list of loc (which field) and msg (what's wrong) — the same structure FastAPI puts in a 422 response body.
Cause: you're on Pydantic v2 with v1 habits
If you upgraded and things broke, v2 changed some names: .dict() → .model_dump(), .parse_obj() → .model_validate(), and Optional[x] without a default is now still required (you must write = None). Many "sudden" ValidationErrors are really a v1→v2 migration gap.
The checklist
- Read the field name, the
msg, and theinput_value— they name the problem. Field required→ pass the field, or give it a default (= None).- Type error → send the right type, or widen the field's type.
- Use
except ValidationError as e: e.errors()to get a clean, structured list. - Just upgraded? Check for v1→v2 API changes (
model_dump,model_validate).
Frequently Asked Questions
How do I make a Pydantic field optional?
Give it a default value. email: str | None = None makes it optional and defaults to None. A field declared with just a type and no default is required in Pydantic v2, even if the type is Optional.
How do I see all the validation errors, not just one?
Catch the exception and call .errors() — except ValidationError as e: print(e.errors()). It returns a list of dicts with loc and msg for every field that failed, so you can fix them all in one pass.
Why does Pydantic reject '25' as a string for an int field?
It usually doesn't — Pydantic coerces "25" to 25. It rejects values it can't parse into the type, like "twenty". If you want strict typing that refuses even coercible strings, use a StrictInt or enable strict mode.
Stop reading, start building
This pairs with a hands-on BytExplorer course — do it on your own machine and actually keep the skill.