---
title: "Manual MongoDB Patch Missing Pydantic Required Fields → 500 on GET"
aliases: [mongodb-manual-patch, pydantic-required-fields-patch, mongo-patch-500]
tags: [mongodb, pydantic, fastapi, debugging, silent-failure]
sources:
  - "daily/2026-05-08.md"
created: 2026-05-08
updated: 2026-05-08
---

# Manual MongoDB Patch Missing Pydantic Required Fields → 500 on GET

When patching a MongoDB document directly (via MongoDB shell, Atlas UI, or a one-off script) without including all fields required by the FastAPI Pydantic response model, the GET endpoint that reads that document returns HTTP 500 with no readable traceback in standard application logs.

## The Failure Mode

```python
# Pydantic response model (simplified)
class JobResponse(BaseModel):
    id: str
    status: str
    occurred_at: datetime   # required — no default
    error_message: Optional[str] = None

# GET /jobs/{id} uses response_model=JobResponse
# If the document in MongoDB is missing 'occurred_at', FastAPI
# will raise ValidationError during serialization → 500, no trace in app logs
```

**Manual patch that triggers the bug:**
```javascript
// MongoDB shell — missing 'occurred_at'
db.jobs.updateOne(
  { _id: ObjectId("...") },
  { $set: { status: "failed", error_message: "network timeout" } }
)
// 'occurred_at' not included → document now fails GET deserialization
```

## Why No Traceback

FastAPI serializes the response model *after* the route handler returns. The `ValidationError` happens in the response rendering layer. Without explicit exception logging on the response serializer, the only visible signal is the 500 status code.

## Fix: Always Include Required Fields in Manual Patches

```javascript
// MongoDB shell — include ALL Pydantic-required fields
db.jobs.updateOne(
  { _id: ObjectId("...") },
  {
    $set: {
      status: "failed",
      error_message: "network timeout",
      occurred_at: new Date()   // ← required field included
    }
  }
)
```

## Diagnosis Checklist

When `GET /entity/{id}` returns 500 after a manual database operation:

1. Check the Pydantic response model for required fields (no `= None` / `= Field(default=...)`)
2. Compare the actual MongoDB document against the model using:
   ```python
   from bson import ObjectId
   doc = db.collection.find_one({"_id": ObjectId("...")})
   print(doc.keys())  # compare against Pydantic model fields
   ```
3. Add any missing required fields to the document
4. Re-test the GET endpoint

## Prevention

When writing admin/debug scripts that patch MongoDB documents:

```python
# Use the Pydantic model as a schema reference
required_fields = [
    name for name, field in JobResponse.model_fields.items()
    if field.is_required()
]
# Verify your patch dict includes all required_fields
```

## Related Concepts

- [[wiki/concepts/fastapi-response-model-silent-field-strip]] — inverse problem: FastAPI silently strips fields not in the response model
- [[wiki/concepts/pydantic-v2-alias-id-gotcha]] — Pydantic v2 Field alias serialization issue

## Sources

- [[daily/2026-05-08.md]] — Discovered during video-accessibility pipeline debugging; `GET /jobs/{id}` returned 500 after a manual MongoDB patch that set `status: "failed"` without including the required `occurred_at` field from the `JobFailure` Pydantic model
