Surface provider error bodies in image generation failures#132
Merged
Conversation
A failed /images/generations call (e.g. seedream-5.0-lite returning 400 from ARK) currently raises httpx's bare HTTPStatusError, whose message is just the status code and URL. The provider's actual rejection reason (invalid parameter, prompt limit, content-filter refusal, ...) lives in the response body and was discarded, making these failures undiagnosable from logs or the client-facing error payload. Wrap both raise_for_status() call sites (the generations/edits request and the hosted-URL fetch) so the raised error carries a compact detail extracted from the body — preferring the JSON error.code/error.message shape, falling back to the raw text, capped at 600 chars — and drop the MDN-link footer from httpx's default message. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Mhie33mj7RR62J61vHYjoF
adambalogh
marked this pull request as ready for review
July 16, 2026 15:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A
seedream-5.0-literequest through/v1/chat/completionsfailed with:{ "error": "Client error '400 Bad Request' for url 'https://ark.ap-southeast.bytepluses.com/api/v3/images/generations'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400", "exception_type": "HTTPStatusError" }The gateway's image-generation path calls
resp.raise_for_status(), and httpx'sHTTPStatusErrormessage only contains the status code and URL. ByteDance ARK (like every OpenAI-compatible provider) puts the actual rejection reason — invalid parameter, prompt length limit, content-filter refusal — in the JSON response body, which was discarded. That makes 400s like this one undiagnosable from either the enclave logs or the client-facing error payload.Change
_provider_error_detail()inimage_generation.py: extracts a compact detail string from an error response, preferring the{"error": {"code", "message"}}shape (also handles a stringerrorfield), falling back to the raw body, capped at 600 chars so a pathological body can't flood logs._raise_for_status_with_detail()and use it at bothraise_for_status()call sites — the/images/generations//images/editsrequest and the hosted-URL fetch. It re-raiseshttpx.HTTPStatusError(soexception_typebucketing is unchanged) with the provider detail appended and httpx's MDN-link footer dropped.With this, the same failure will read e.g.:
Testing
TestProviderErrorDetailcases pin: error body surfaced fromgenerate_images, JSONerror.code/error.messageextraction, stringerrorfield, non-JSON fallback, empty body, truncation, and the streamed URL-fetch error path.test_ohttpimport error (pytestnot installed in the env, unrelated).make lint(ruff + mypy) clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01Mhie33mj7RR62J61vHYjoF
Generated by Claude Code