---
title: "Pydantic Required Fields Break GET After Manual MongoDB Patch"
description: "Manually patching a MongoDB document without all required Pydantic model fields causes every GET of that document to return 500 with no useful stack trace"
tags: [pydantic, mongodb, debugging, fastapi, silent-failure]
source: daily/2026-05-08.md
created: 2026-05-08
updated: 2026-05-08
---

# Pydantic Required Fields Break GET After Manual MongoDB Patch

## The Problem

When a MongoDB document is manually patched (via compass, mongosh, or admin script) to add a nested object, all required Pydantic fields in that nested model must be present. If any are missing, every `GET` request for that document will return `500 Internal Server Error`. The error happens during Pydantic deserialization — not during the write — so the patch appears to succeed.

## Example

```python
# Pydantic model — failure field is optional but has required sub-fields
class JobFailure(BaseModel):
    error_code: str          # required
    message: str             # required
    occurred_at: datetime    # required ← easy to forget in manual patches

class Job(BaseModel):
    id: str
    status: str
    failure: Optional[JobFailure] = None
```

Manual patch in mongosh:
```javascript
// WRONG — missing occurred_at
db.jobs.updateOne(
  { _id: ObjectId("...") },
  { $set: { failure: { error_code: "TTS_ERROR", message: "API timeout" } } }
)
// Appears to succeed ✓
// But every GET /jobs/<id> now returns 500
```

```javascript
// CORRECT — all required fields included
db.jobs.updateOne(
  { _id: ObjectId("...") },
  { $set: { failure: { 
      error_code: "TTS_ERROR", 
      message: "API timeout",
      occurred_at: new Date()   // ← required field
  }}}
)
```

## Diagnosis

The 500 often has no useful message in standard FastAPI logs. To get the Pydantic validation error:

1. Check the full exception log (not just the HTTP error response)
2. Add `exc_info=True` logging to the exception handler, or temporarily set `LOG_LEVEL=DEBUG`
3. Look for `ValidationError` with `field required` in the trace

## Why It's Hard to Spot

- MongoDB has no schema enforcement by default — the write succeeds even with missing fields
- The failure happens at read time (GET), not write time — making causality non-obvious
- The error appears as a generic 500 on the endpoint, not as a database or serialization error in the response body

## Prevention

- Use the Pydantic model's schema to verify manual patches: `JobFailure.schema()` shows all required fields
- For admin operations, prefer writing a Python script that constructs the model object and then calls `.model_dump()` to get a valid document

## Related

- [[wiki/concepts/pydantic-v2-alias-id-gotcha]] — other Pydantic serialization gotchas
- [[wiki/concepts/pydantic-model-dict-interface]] — Pydantic model passed where dict expected
