Skip to content

Bug: /v1/users/people returns 500 — ResponseValidationError on Person model #5423

@beastoin

Description

@beastoin

GET /v1/users/people returns 500 (ResponseValidationError) for users who have at least one malformed person document in Firestore. 52 failures in 24h across 8 affected users. Same Pydantic validation pattern as #5409 (ConversationSource enum) but on a different model and endpoint.

Current Behavior

  • get_people() (database/users.py:67-70) returns raw Firestore dicts via to_dict()
  • FastAPI validates each dict against the Person model (models/other.py:21-28) which requires id: str, name: str, created_at: datetime, updated_at: datetime
  • If ANY person doc has a missing or invalid required field, ResponseValidationError → 500 for the entire endpoint
  • One bad doc locks the user out of the people list (same pattern as Bug: ResponseValidationError on /v1/conversations — unknown source value breaks enum serialization #5409)
  • Response latencies 42-265ms confirm fast validation failure, not timeout

Expected Behavior

Endpoint should either skip malformed docs gracefully or the Person model should have resilient defaults for optional fields.

Affected Areas

File Line Description
backend/database/users.py 67-70 get_people() returns raw to_dict() with no validation or doc ID injection
backend/database/users.py 61-64 get_person() same pattern
backend/routers/users.py 303-312 GET endpoint returns raw dicts, Pydantic validates on response
backend/routers/users.py 289-300 Single person GET endpoint, same pattern
backend/models/other.py 21-28 Person model with strict required fields

Solution

Two options (can combine):

Option A: Make Person model resilient — add Optional with defaults for fields that may be missing in legacy docs, add _missing_() or validator fallbacks (same approach as #5411 for ConversationSource).

Option B: Inject document ID and filter bad docs in get_people():

def get_people(uid: str):
    people_ref = db.collection('users').document(uid).collection('people')
    people = people_ref.stream()
    result = []
    for person in people:
        data = person.to_dict()
        data.setdefault('id', person.id)  # Ensure doc ID is present
        result.append(data)
    return result

Files to Modify

  • backend/database/users.py — inject doc ID, handle missing fields
  • backend/models/other.py — make Person model resilient to missing fields

Impact

8 affected users currently. Any user with a legacy or externally-created person doc missing required fields will be locked out of their people list.

Related


by AI for @beastoin

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend Task (python)bugSomething isn't workingp2Priority: Important (score 14-21)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions