Summary
v7.2.127-5 introduced a regression that breaks Codex OAuth gpt-5.6-* models (gpt-5.6-luna / gpt-5.6-terra / gpt-5.6-sol). Valid upstream responses are misclassified as empty completions, which then triggers the empty-completion retry logic, exhausts retries with 503, and puts the auth into cooldown — after which all subsequent requests are instantly rejected with auth_unavailable.
Symptom
First request(s) fail with:
{"error":{"message":"empty_completion: upstream returned an empty completion; attempted routes: [codex:503]","type":"server_error","code":"internal_server_error"}}
Subsequent requests fail instantly (~1ms) with:
{"error":{"message":"auth_unavailable: auth_unavailable: no auth available (providers=codex, model=gpt-5.6-luna)","type":"server_error","code":"internal_server_error"}}
Bisect (empirical, same host / same auth / same egress IP)
Each version was tested in an isolated container with an identical copy of production config.yaml + auths/, calling POST /v1/responses with {"model":"gpt-5.6-*","input":"pong","max_output_tokens":16}:
| Version |
Result |
Notes |
v7.2.127-3 |
✅ 9/9 HTTP 200 |
works |
v7.2.127-4 |
✅ 6/6 HTTP 200 |
works (vet-clean only) |
v7.2.127-5 |
❌ 0/6 |
first round empty_completion, second round auth_unavailable (cooldown) |
v7.2.127-6 |
❌ 0/3 |
same failure signature, inherited from 127-5 |
→ The regression is introduced in v7.2.127-5, i.e. the large empty-completion / SSE parsing / stream-drain batch (PR #175 / #178 / #179 / #182). 127-4 and 127-6 (Devin provider) are unaffected by themselves.
Environment
- Auth: Codex OAuth,
chatgpt_plan_type=prolite (subscription valid; available_in_plans for gpt-5.6-* includes prolite in the model catalog)
- Same account works fine against upstream
router-for-me/CLIProxyAPI v7.2.137
- Non-Codex providers (Kiro, AWS Claude) are unaffected on
127-5/127-6
- Deployment: Docker (
kaitranntt/cli-proxy-api-plus images), Linux x86_64
Reproduction
- Run
v7.2.127-5 (or -6) with a valid Codex OAuth auth file
POST /v1/responses with {"model":"gpt-5.6-luna","input":"pong","max_output_tokens":16}
- Observe
empty_completion 503, then auth_unavailable on subsequent calls until cooldown expires
- Run the same request against
v7.2.127-4 or v7.2.127-3 → HTTP 200
Possibly related
Note that #186 (upstream-sync blocked for v7.2.137) conflicts exactly in internal/translator/codex/openai/responses/codex_openai-responses_request_test.go — the same area this regression lives in. When resolving that conflict, it may be worth re-validating the fork-side empty-completion detection against real Codex /v1/responses traffic (the 127-5 test codex-responses terminal frames are never empty completions passes, but real responses still get misclassified).
Happy to provide more logs or run additional tests if helpful.
Summary
v7.2.127-5introduced a regression that breaks Codex OAuthgpt-5.6-*models (gpt-5.6-luna/gpt-5.6-terra/gpt-5.6-sol). Valid upstream responses are misclassified as empty completions, which then triggers the empty-completion retry logic, exhausts retries with 503, and puts the auth into cooldown — after which all subsequent requests are instantly rejected withauth_unavailable.Symptom
First request(s) fail with:
{"error":{"message":"empty_completion: upstream returned an empty completion; attempted routes: [codex:503]","type":"server_error","code":"internal_server_error"}}Subsequent requests fail instantly (~1ms) with:
{"error":{"message":"auth_unavailable: auth_unavailable: no auth available (providers=codex, model=gpt-5.6-luna)","type":"server_error","code":"internal_server_error"}}Bisect (empirical, same host / same auth / same egress IP)
Each version was tested in an isolated container with an identical copy of production
config.yaml+auths/, callingPOST /v1/responseswith{"model":"gpt-5.6-*","input":"pong","max_output_tokens":16}:v7.2.127-3v7.2.127-4v7.2.127-5empty_completion, second roundauth_unavailable(cooldown)v7.2.127-6→ The regression is introduced in
v7.2.127-5, i.e. the large empty-completion / SSE parsing / stream-drain batch (PR #175 / #178 / #179 / #182).127-4and127-6(Devin provider) are unaffected by themselves.Environment
chatgpt_plan_type=prolite(subscription valid;available_in_plansforgpt-5.6-*includesprolitein the model catalog)router-for-me/CLIProxyAPIv7.2.137127-5/127-6kaitranntt/cli-proxy-api-plusimages), Linux x86_64Reproduction
v7.2.127-5(or-6) with a valid Codex OAuth auth filePOST /v1/responseswith{"model":"gpt-5.6-luna","input":"pong","max_output_tokens":16}empty_completion503, thenauth_unavailableon subsequent calls until cooldown expiresv7.2.127-4orv7.2.127-3→ HTTP 200Possibly related
Note that #186 (upstream-sync blocked for v7.2.137) conflicts exactly in
internal/translator/codex/openai/responses/codex_openai-responses_request_test.go— the same area this regression lives in. When resolving that conflict, it may be worth re-validating the fork-side empty-completion detection against real Codex/v1/responsestraffic (the127-5testcodex-responses terminal frames are never empty completionspasses, but real responses still get misclassified).Happy to provide more logs or run additional tests if helpful.