Skip to content

fix(server): preserve JSON rejection statuses - #406

Open
ting-hong-shieh wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
ting-hong-shieh:fix/400-preserve-json-rejection-status
Open

fix(server): preserve JSON rejection statuses#406
ting-hong-shieh wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
ting-hong-shieh:fix/400-preserve-json-rejection-status

Conversation

@ting-hong-shieh

@ting-hong-shieh ting-hong-shieh commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

What

  • preserve the status code carried by Axum JsonRejection
  • keep non-object and protocol-decode body errors at HTTP 400
  • retain the existing OpenAI-compatible and Anthropic error renderers
  • cover malformed JSON, missing/unsupported content type, and oversized bodies

Why

The shared JSON helper reduced every extractor rejection to a string, and invalid_body_error then hard-coded HTTP 400. Clients therefore lost Axum's 415 and 413 distinctions, and Anthropic's existing request_too_large mapping was unreachable for oversized JSON bodies.

Closes #400

Validation

  • cargo test -p switchyard-server --test server json_extractor_statuses_keep_api_specific_error_envelopes -- --nocapture — passed
  • cargo test -p switchyard-server — passed
  • cargo fmt --all --check — passed
  • cargo clippy --workspace --all-targets -- -D warnings — passed
  • cargo test --workspace — passed with loopback access enabled for the repository's local mock servers
  • git diff --check — passed

No live provider calls or secrets were used.

Summary by CodeRabbit

  • Bug Fixes
    • Invalid request bodies now preserve the appropriate HTTP status codes instead of being returned as generic bad requests.
    • Improved error responses for malformed JSON, unsupported media types, and oversized request bodies.
    • Consistent API-specific error envelopes are now returned across Chat Completions and Anthropic Messages endpoints.

Signed-off-by: Ting-Hong Shieh <32212900+ting-hong-shieh@users.noreply.github.com>
@ting-hong-shieh

Copy link
Copy Markdown
Contributor Author

Before / after HTTP snapshot

I ran the same focused in-process Axum request matrix at the PR base (b256d936) and current head (caed4eff). The requests are rejected by extraction before routing, so no upstream/provider call was involved.

OpenAI Chat endpoint:

Input Before status After status After envelope
malformed JSON + application/json 400 400 invalid_request_error / invalid_body
valid JSON, missing Content-Type 400 415 invalid_request_error / invalid_body
valid JSON + unsupported Content-Type 400 415 invalid_request_error / invalid_body
body larger than 32 MiB 400 413 invalid_request_error / invalid_body

Anthropic Messages endpoint:

Input Before status/type After status/type
malformed JSON + application/json 400 / invalid_request_error 400 / invalid_request_error
valid JSON, missing Content-Type 400 / invalid_request_error 415 / api_error
body larger than 32 MiB 400 / invalid_request_error 413 / request_too_large

The outer Anthropic envelope remains {"type":"error", ...}; the change restores Axum's rejection status and lets the existing protocol renderer select the status-appropriate error type.

@ting-hong-shieh
ting-hong-shieh marked this pull request as ready for review August 13, 2026 15:39
@ting-hong-shieh
ting-hong-shieh requested a review from a team as a code owner August 13, 2026 15:39
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7b07d603-bcc0-4e64-aff8-73758531b2da

📥 Commits

Reviewing files that changed from the base of the PR and between b256d93 and caed4ef.

📒 Files selected for processing (2)
  • crates/switchyard-server/src/lib.rs
  • crates/switchyard-server/tests/server.rs

Walkthrough

The server now preserves JSON extractor HTTP statuses, including 415 Unsupported Media Type and 413 Payload Too Large. Tests cover malformed JSON, unsupported media types, oversized bodies, and API-specific error envelopes.

Changes

Request body error handling

Layer / File(s) Summary
Preserve extractor status codes
crates/switchyard-server/src/lib.rs
Body decoding now returns the extractor status with its error message. Invalid-body responses use the supplied status, while non-object JSON and route decoding errors remain 400 Bad Request.
Validate request body responses
crates/switchyard-server/tests/server.rs
Added raw-body request support and tests for malformed JSON, missing or unsupported content types, and oversized bodies across Chat Completions and Anthropic Messages endpoints.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to caed4

The change preserves API-specific JSON rejection statuses while retaining existing error envelopes, with no actionable merge-blocking risk remaining after normal checks and review.

Poem

I’m a rabbit guarding JSON at night,
Keeping four-oh-four? No—statuses right.
Four-one-five for types astray,
Four-one-three when bytes outweigh.
Tests hop through each error door,
And envelopes say what they’re for. 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes preserving JSON rejection HTTP statuses, which is the primary change.
Linked Issues check ✅ Passed The changes satisfy issue #400 by preserving 415, 413, and 400 statuses while retaining OpenAI and Anthropic error mappings.
Out of Scope Changes check ✅ Passed The implementation and regression tests directly support issue #400 and contain no unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Comment @coderabbitai help to get the list of available commands.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] Server collapses JSON extractor errors to HTTP 400

1 participant