fix: prevent 400 format errors from triggering compression loop on Codex Responses API (#6751)

The error classifier's generic-400 heuristic only extracted err_body_msg from
the nested body structure (body['error']['message']), missing the flat body
format used by OpenAI's Responses API (body['message']). This caused
descriptive 400 errors like 'Invalid input[index].name: string does not match
pattern' to appear generic when the session was large, misclassifying them as
context overflow and triggering an infinite compression loop.

Added flat-body fallback in _classify_400() consistent with the parent
classify_api_error() function's existing handling at line 297-298.
This commit is contained in:
Teknium
2026-04-09 11:11:34 -07:00
committed by GitHub
parent 2f0a83dd12
commit 3007174a61
2 changed files with 35 additions and 0 deletions
+32
View File
@@ -507,6 +507,38 @@ class TestClassifyApiError:
assert result.reason == FailoverReason.format_error
assert result.retryable is False
def test_400_flat_body_descriptive_not_context_overflow(self):
"""Responses API flat body with descriptive error + large session → format error.
The Codex Responses API returns errors in flat body format:
{"message": "...", "type": "..."} without an "error" wrapper.
A descriptive 400 must NOT be misclassified as context overflow
just because the session is large.
"""
e = MockAPIError(
"Invalid 'input[index].name': string does not match pattern.",
status_code=400,
body={"message": "Invalid 'input[index].name': string does not match pattern.",
"type": "invalid_request_error"},
)
result = classify_api_error(e, approx_tokens=200000, context_length=400000, num_messages=500)
assert result.reason == FailoverReason.format_error
assert result.retryable is False
def test_400_flat_body_generic_large_session_still_context_overflow(self):
"""Flat body with generic 'Error' message + large session → context overflow.
Regression: the flat-body fallback must not break the existing heuristic
for genuinely generic errors from providers that use flat bodies.
"""
e = MockAPIError(
"Error",
status_code=400,
body={"message": "Error"},
)
result = classify_api_error(e, approx_tokens=100000, context_length=200000)
assert result.reason == FailoverReason.context_overflow
# ── Peer closed + large session ──
def test_peer_closed_large_session(self):