Repository navigation
Direct mode relays transient Daybreak Blue account-model 400 without a bounded retry #2183
Description
Activity
coderabbitai commented
on Aug 20, 2026 coderabbitaiboton Aug 20, 2026 – with coderabbitaiContributorMore actions🔗 Related PRs
#2137 - fix(responses): stop requiring a ChatGPT credential for routed providers [merged]
#2147 - fix(xai): stream OAuth Grok through Responses [merged]
#2162 - fix(anthropic): frame the opening turn so AgentRouter stops blocking non-English [merged]
#2169 - fix(auth): key admission-bearer substitution on transport, not provider name [merged]
#2104 - fix(xai): stream OAuth Grok through Responses [open]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.- Create Plan
🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:issue_enrichment: auto_enrich: enabled: false
💬 Have feedback or questions? Drop into our discord!
- addedaccount-poolOAuth, credentials, Codex pool, quota, failover, plansOAuth, credentials, Codex pool, quota, failover, plans
on Aug 20, 2026 github-actions commented
on Aug 20, 2026 on Aug 20, 2026 – with GitHub ActionsContributorMore actionsIssue reopened
The report now contains the information required by the automated check. Thanks for updating it.
리뷰 · 우선순위 70 / 80
재현이 코드랑 맞음.
src/server/responses/core.ts에isAllowListedCodexAccountModel400이 이 400 문구 그대로 잡고,shouldRetryCodexPoolAccountModel400이 그걸로 재시도 여부를 봄. 문제는 호출부가usesCodexForwardPoolAuth뒤에만 있음. 2887줄.authCtx.kind가pool/main-pool이고authMode: forward+openai-responses일 때만임.codexAccountMode: direct는 그 가드를 못 통과해서 162번 성공한 스레드가 한 방 400에 죽음. 이슈가 말한 그대로임.풀 쪽은 이미 세게 막아놨음. 같은 파일이 같은 계정으로 최대 7번 더 보냄(원본 포함 8번).
retrySameConfirmedAccount가ACCOUNT_GATED_NATIVE_OPENAI_MODELS일 때임. 그 집합은src/codex/catalog/native-models.ts에서gpt-daybreak-blue-latest하나임. 쿼터 429/402 교체는 히스토리대로 한 번. 다이렉트에 쿼터 페일오버를 가져오면 안 됨. 이 이슈가 달라는 건 allow-list 400의 같은 계정 재시도뿐임.더 웃긴 점 있음.
applyCodexAccountGatedWireNormalization이 셀렉터를gpt-5.6-sol로 바꿔서 샤드 400을 피하라고 적혀 있음. 근데 로그 바디가 아직도'gpt-daybreak-blue-latest' model is not supported임. 와이어에 셀렉터가 그대로 나갔다는 뜻임. 정규화가 다이렉트 경로에서 안 돌았거나, 돌고도 업스트림이 셀렉터로 거절한 거임. 재시도만 넣으면 증상은 줄고, 셀렉터가 남는 한 같은 400은 또 옴.formatPassthroughUpstreamError는 이{detail:...}바디를 그대로 통과시킴. 클라가 받는 에러가 정직해서 풀 재시도 판별이 됨. 다이렉트는 그 정직한 400을 그냥 턴 종료로 씀. 패시브가 문제는 아님.해결방안: 다이렉트 포워드에도 이 allow-list 400만 같은 계정 bounded retry를 열어라.
retryCodexPoolOnAlternateAccount를 통째로 열지 말고, 같은 계정 루프만 빼서fixedAccount/direct에도 태워라. 쿼터 교체랑 RR은 풀 전용으로 남겨라. 추가로 다이렉트에서applyCodexAccountGatedWireNormalization이 실제로 도는지 로그로 확인해라. 와이어가 계속 셀렉터면 재시도는 반창고임. types/config 스플릿이랑 무관함. 2.28 태그 다음에 바로 손댈 만함.이 댓글은 grok-bot이 작성했습니다
Reacted by ZeroDiI verified this against the current release rather than relying on the earlier review conclusion.
The report is from 2.27.0. The relevant fix landed in commit
0bce9516dand is included in 2.28.0, released on August 20, 2026 after this issue was opened. On the current path,applyCodexAccountGatedWireNormalization()runs after the final auth context is resolved and before the upstream request is built, regardless of whether the provider is in Pool or Direct mode. Forgpt-daybreak-blue-latest, it preserves Daybreak as the catalog/entitlement identity but sendsgpt-5.6-solon the authenticated wire and removesprompt_cache_retention.That means the 2.27.0 response body naming
gpt-daybreak-blue-latestis evidence that the old, pre-normalization path was still in use. I am not adding Pool failover or broad account retry behavior to Direct mode at this point: the current fix removes the rejected selector before dispatch, and Direct must not silently inherit Pool account-switching semantics.Please upgrade to 2.28.0 and retry the same long-lived Direct conversation. If the exact 400 still occurs on 2.28.0, please attach one redacted request-log row showing the OCX version, route kind, adapter, account mode, public selector, HTTP status, and error body. Do not include credentials, account IDs, thread IDs, or raw turn metadata. I am keeping the issue open as
needs-infountil we have a current-version result.Reacted by ZeroDi- addedneeds-infoWaiting on reporter for a concrete spec or reproductionWaiting on reporter for a concrete spec or reproduction
on Aug 20, 2026 Upgraded to OpenCodex 2.28.0 and resumed the same long-lived Direct conversation with Daybreak Blue. The request completed successfully, and the previous account-model 400 did not reproduce.
Thanks for retesting the same long-lived Direct conversation on OpenCodex 2.28.0.
That confirms the observed 2.27.0 failure was on the pre-normalization path. In 2.28.0, Daybreak remains the catalog/entitlement identity while the authenticated wire request is normalized to the supported native model and the unsupported cache-retention field is removed. Since the original reporter can no longer reproduce the account-model 400 after upgrading, I am closing this as fixed by
0bce9516d/ 2.28.0.If the exact error returns on 2.28.0 or later, please open a new report (or ask us to reopen this one) with the current version, request-log ID, and sanitized provider-debug rows so we can distinguish a stale runtime from a new upstream rejection.
Client or integration
Codex App
Area
Authentication and account pool
Summary
In
codexAccountMode: direct, a transient upstream Daybreak Blue account-model rejection is relayed immediately and terminates the active Codex turn/thread.The same conversation completed 162 requests with HTTP 200 using the same bare native model, provider, adapter, and route. The next request returned the exact HTTP 400 below once, after which the conversation stopped. Other conversations continued to receive successful responses.
Expected: OpenCodex should apply one bounded same-account retry for this exact pre-stream rejection in direct mode, or otherwise prevent a single transient entitlement response from stranding a healthy long-running task.
Reproduction
authMode: forwardandcodexAccountMode: direct.gpt-daybreak-blue-latestmodel in Codex Desktop.openai-responseson the native route.This is intermittent. In the affected conversation, 162 requests succeeded before one request failed. In the nearby usage-ledger sample, Daybreak Blue produced 1,373 HTTP 200 responses and one occurrence of this exact HTTP 400.
The removed legacy custom row
openai/gpt-daybreak-blue-latestwas not involved. Both the successful and failing requests in the affected conversation used the bare nativegpt-daybreak-blue-latestroute.The existing
shouldRetryCodexPoolAccountModel400()path recognizes this response, but the retry is guarded byusesCodexForwardPoolAuth(...); direct mode relays it immediately.Version
2.27.0
Operating system
Windows 11
Provider and model
openai / gpt-daybreak-blue-latestLogs or error output
Provider: openai Adapter: openai-responses Account mode: direct Auth mode: forward Route kind: native Admission kind: loopback Inbound protocol: responses Requested effort: medium Status: 400 {"detail":"The 'gpt-daybreak-blue-latest' model is not supported when using Codex with a ChatGPT account."}Redacted configuration
{ "providers": { "openai": { "adapter": "openai-responses", "baseUrl": "https://chatgpt.com/backend-api/codex", "authMode": "forward", "codexAccountMode": "direct" } } }Checks