From 4655263f35fc51ca4b3ec3bfde3979d4a441fb33 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Wed, 16 Sep 2026 10:12:26 -0700 Subject: [PATCH] fix(agent): apply the oversize content-field rule on the 422 path too pydantic relays (#104731) report the same content-field detail with HTTP 422; the 422 handler ran only the keyword rules, so a Nebius-shaped rejection behind such a relay would still be claimed by the multimodal tool-content rule. Sibling site of #112473. --- agent/error_classifier.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/agent/error_classifier.py b/agent/error_classifier.py index e4c5d9fed7..b0b8b1935d 100644 --- a/agent/error_classifier.py +++ b/agent/error_classifier.py @@ -916,6 +916,13 @@ def _classify_400(c: _Ctx) -> Verdict: return _V_FORMAT_ERROR +def _classify_image_tool_422(c: _Ctx) -> Verdict: + """422: pydantic relays report the same content-field shapes as 400 (#104731, #112473).""" + if _oversized_message_content_rejection(c.body): + return _V_IMAGE_TOO_LARGE + return _first_match(c.msg, _IMAGE_TOOL_RULES) or _V_FORMAT_ERROR + + # 401 not retryable on its own: rotation/refresh run before the retryability # check, then the client-error abort path (fallback first) is correct. 408 is # retry-safe (RFC 9110 ยง15.5.9; proxies emit it when generation outruns the @@ -923,7 +930,7 @@ def _classify_400(c: _Ctx) -> Verdict: _STATUS_HANDLERS: Dict[int, Callable[[_Ctx], Verdict]] = { 400: _classify_400, 401: lambda c: _V_AUTH_ROTATE, 402: lambda c: _classify_402(c.msg, dict), 403: _status_403, 404: _status_404, 408: lambda c: _V_TIMEOUT, 413: lambda c: _V_PAYLOAD_TOO_LARGE, - 422: lambda c: _first_match(c.msg, _IMAGE_TOOL_RULES) or _V_FORMAT_ERROR, + 422: lambda c: _classify_image_tool_422(c), 429: _status_429, 500: _status_5xx, 502: _status_5xx, 503: lambda c: _first_match(c.msg, _OVERFLOW_AS_5XX_RULES) or _V_OVERLOADED, 529: lambda c: _first_match(c.msg, _OVERFLOW_AS_5XX_RULES) or _V_OVERLOADED,