Skip to content

fix(routing): unhandled Pydantic ValidationError on malformed router section output causes untraced 500 #252

Closed

Description

@piyushmakhija28

Summary

route_query() constructs RelevantSection objects from raw router output without catching pydantic.ValidationError. If the router module returns a section with page_start > page_end or a section_id not matching ^sec_[A-Za-z0-9]+$, the Pydantic model validator raises ValidationError — caught only by the global 500 handler, producing a response with no query_id and no way to correlate the error to the failing request.

Root Cause

backend/app/api/routing.py around lines 119–135:

sections = [
    RelevantSection(        # ← ValidationError if section_id pattern fails
        section_id=s.section_id,
        page_start=s.page_start,   # ← _page_range_valid raises if start > end
        page_end=s.page_end,
        ...
    )
    for s in decision.relevant_sections
]

# query_id is assigned AFTER this loop:
query_id = str(uuid4())   # ← never reached if ValidationError is raised above
return RouteResponse(query_id=query_id, ...)

The 500 response has no query_id field, so operators cannot correlate the server-side log with the client's error report.

Failure Scenario

  1. A router module bug returns page_start=10, page_end=5 for a section.
  2. RelevantSection._page_range_valid validator raises pydantic.ValidationError.
  3. Global _handle_http_exception converts it to HTTP 500 with body {"code": "INTERNAL_ERROR"}.
  4. Client sees a 500 with no query_id. Cannot file a support ticket with a correlation ID.
  5. Server logs show the exception but no query_id to link it to the client's report.

Proposed Fix

query_id = str(uuid4())    # ← generate BEFORE building sections

try:
    sections = [
        RelevantSection(
            section_id=s.section_id,
            page_start=s.page_start,
            page_end=s.page_end,
            rationale=s.rationale,
        )
        for s in decision.relevant_sections
    ]
except ValidationError as exc:
    logger.error(
        "Router returned invalid section data",
        extra={"query_id": query_id, "error": str(exc)},
    )
    raise RouterOutputError(f"Invalid section data from router: {exc}") from exc

Map RouterOutputError to a 502 (Bad Gateway) so callers know the upstream module (not their request) is the problem.

Activity

  1. added
    bugSomething isn't working
    priority: highData loss, security, or major correctness bug
    code-reviewFound via automated code review
    on Jun 21, 2026
  2. piyushmakhija28 commented on Jun 21, 2026

    @piyushmakhija28
    ContributorAuthor

    Fixed in PR #280 (Sprint R3/R4: fix(sprint-r3): root-cause fixes for all 39 bugs from code review round 3 + Sprint R4 round 4)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcode-reviewFound via automated code reviewpriority: highData loss, security, or major correctness bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions