Skip to content

Direct mode relays transient Daybreak Blue account-model 400 without a bounded retry #2183

Description

@0disoft

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

  1. Configure the native OpenAI provider with authMode: forward and codexAccountMode: direct.
  2. Select the bare native gpt-daybreak-blue-latest model in Codex Desktop.
  3. Run a long-lived task that performs many continuation turns.
  4. Observe successful requests through openai-responses on the native route.
  5. When the exact account-model HTTP 400 occurs once, observe that the active turn stops without a bounded same-account retry.

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-latest was not involved. Both the successful and failing requests in the affected conversation used the bare native gpt-daybreak-blue-latest route.

The existing shouldRetryCodexPoolAccountModel400() path recognizes this response, but the retry is guarded by usesCodexForwardPoolAuth(...); direct mode relays it immediately.

Version

2.27.0

Operating system

Windows 11

Provider and model

openai / gpt-daybreak-blue-latest

Logs 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

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. coderabbitai commented on Aug 20, 2026

    @coderabbitai
    Contributor
    🔗 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 plan command 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!

  2. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    Issue reopened

    The report now contains the information required by the automated check. Thanks for updating it.

  3. lidge-jun commented on Aug 20, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 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이 작성했습니다

  4. Ingwannu commented on Aug 20, 2026

    @Ingwannu
    Owner

    I 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 0bce9516d and 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. For gpt-daybreak-blue-latest, it preserves Daybreak as the catalog/entitlement identity but sends gpt-5.6-sol on the authenticated wire and removes prompt_cache_retention.

    That means the 2.27.0 response body naming gpt-daybreak-blue-latest is 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-info until we have a current-version result.

  5. added
    needs-infoWaiting on reporter for a concrete spec or reproduction
    on Aug 20, 2026
  6. 0disoft commented on Aug 21, 2026

    @0disoft
    ContributorAuthor

    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.

  7. Ingwannu commented on Aug 21, 2026

    @Ingwannu
    Owner

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, plansbugSomething isn't workingneeds-infoWaiting on reporter for a concrete spec or reproduction

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions