Skip to content

[Bug]: 2.42.0 Plus quota exhaustion causes 18 incomplete failures without switching to main (related to #3795) #3994

Closed as duplicate

Description

@FacuM

Client or integration

Codex Responses traffic through the local OpenCodex proxy. Configured Codex runtime: 0.153.4.

Area

Authentication and account pool

Summary

On an installation whose package.json reports 2.42.0, an exhausted ChatGPT Plus pool account received 18 consecutive quota failures without automatic failover to the main account. Auto-switch threshold was configured as 95%. Subsequent requests using the main account succeeded.

Known-bug field confirmation, not a claim of a regression on current releases: this matches the incomplete-terminal accounting defect in #3795, fixed by #3791. The maintainer confirmed that fix in v2.46.0. This report adds a short-window exhaustion occurrence and sanitized evidence from 2.42.0; it can be linked/closed as a duplicate of #3795. No reproduction on v2.46.0 or v2.47.0 has been performed.

Expected: quota-bearing incomplete terminals should update account health and allow the next eligible non-fixed request to select a healthy account. This does not require replaying an already-started stream.

Reproduction

Observed production sequence (not a newly executed live quota-exhaustion test):

  1. Configure main plus one additional ChatGPT Plus account, with autoSwitchThreshold: 95.
  2. Send ordinary native-model Responses requests using bare gpt-6-astra (not an explicit account namespace).
  3. Exhaust the Plus account's five-hour window.
  4. Continue sending requests. In this occurrence, 18 consecutive requests remained on that account, each logging The usage limit has been reached, status 502, and terminal incomplete.
  5. Requests subsequently routed to main and returned 200. The on-disk configuration inspected afterward had main active and manually pinned. The logs establish recovery on main, but do not by themselves establish who/what initiated that account change.

Version

2.42.0 from the installed @bitkyc08/opencodex/package.json. Exact running process revision was not independently captured.

Operating system

Linux 6.19.11-1-cachyos, x86_64 GNU/Linux.

Provider and model

OpenAI / ChatGPT Codex account pool, gpt-6-astra, native-family routing, Responses protocol, loopback admission.

Logs or error output

Sanitized aggregation from local usage.jsonl, all times UTC on 2026-09-08:

First Plus quota failure:     03:14:25.098
Last Plus quota failure:      03:15:38.060
Consecutive quota failures:   18
Attempts per failed request:  1 (all 18)
Recovery kinds:               [] (all 18)
First subsequent main 200:    03:16:01.316

status:          502
errorCode:       upstream_server_error
upstreamError:   The usage limit has been reached
terminalStatus:  incomplete
closeReason:     terminal
usageStatus:     unreported
requestedModel:  gpt-6-astra
routeKind:       native
selected.reason: native-family

Persisted quota snapshot inspected after the event:

Plus snapshot updatedAt: 2026-09-08T03:14:03.135Z
Plus shortPercent: 100
Plus shortWindowSeconds: 18000
Plus shortResetAt: 1788840169
Plus weeklyPercent: 16
Main weeklyPercent: 11

Main's short-window percentage was absent, not measured as zero. The disk snapshot does not prove that the serving process used that same in-memory snapshot for every failed admission.

Source inspection and likely mechanism

The installed source still contains the known pre-fix behavior:

  • src/server/responses/core.ts:1382-1395, codexForwardTerminalOutcomeRecorder: every status === "incomplete" unconditionally calls recordCodexUpstreamOutcome(..., 200, ...) and returns, clearing failure evidence rather than recording quota exhaustion.
  • src/server/request-log.ts:874: after the policy check, captureTerminalHttpStatus returns for anything other than response.failed; it does not classify an incomplete quota message as semantic 429/402.

This explains the missing quota-health signal despite a visible 502 in request logs and matches #3795/#3791. The additional question of why the persisted short-window snapshot did not prevent those admissions cannot be conclusively answered from these files alone; do not interpret this report as proof of a separate selector defect.

Redacted configuration

Relevant observed settings (account identifiers replaced):

{
  "autoSwitchThreshold": 95,
  "codexAccountPriorities": {"PLUS_ACCOUNT": 2},
  "codexAccounts": [{"id": "PLUS_ACCOUNT", "plan": "plus", "isMain": false}],
  "activeCodexAccountId": "__main__",
  "activeCodexAccountPinned": "__main__"
}

The active/pinned fields are the post-incident state, not an assertion about the state before exhaustion. No configuration, credentials, installed code, or service state was modified during this investigation.

Checks

Activity

  1. added
    bugSomething isn't working
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    on Sep 8, 2026
  2. lidge-jun commented on Sep 8, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 24 / 80

    이 이슈는 설치본 2.42.0에서 ChatGPT Plus Pool 계정이 단기 쿼터를 소진한 뒤, incomplete 터미널 18연속이 나와도 main으로 안 넘어간 관측을 적습니다. 작성자도 인정하듯 이는 현재 tip 회귀 주장이 아니라, 이미 알려진 incomplete 쿼터 회계 결함 #3795의 짧은 창 재발생 증거입니다. #3795는 #3791(fix(responses): preserve incomplete quota attribution)으로 고쳐졌고, 메인테이너가 v2.46.0에 포함됐다고 확인한 계열입니다. 지금 dev는 package 2.48.0, HEAD 402be7c1f입니다.

    HEAD의 src/server/responses/core.ts codexForwardTerminalOutcomeRecorder는 incomplete이면서 429/402 quota status가 없으면 계정에 200(성공)으로 기록해 soft-avoid를 풀고, quota status가 있으면 그 semantic status로 health를 갱신합니다. 2.42.0에 있던 “incomplete를 성공/무시처럼 취급해 rotation이 안 도는” 구멍과는 반대 방향입니다. 로그의(502 + usage limit + incomplete + recoveryKinds 빈 배열 + 이후 main 200)는 구버전 증상과 잘 맞습니다. 다만 디스크에 main pin이 남아 있어, 마지막 전환이 자동 failover인지 수동 pin인지는 이 로그만으로 단정할 수 없습니다. 작성자가 그 한계도 솔직히 적었습니다.

    v2.46+/현재 dev에서 같은 18연속을 재현했다는 증거는 없습니다. #3996/#3997(신선 요청 cooldown vs caller main)과는 메커니즘이 다릅니다. 여기 이슈를 새 버그로 키우면 큐만 부풀어 #3795 중복이 됩니다.

    경로 src/server/responses/core.ts codexForwardTerminalOutcomeRecorder (HEAD) - incomplete+quota status면 health 반영, quota 없는 incomplete는 200 처리. #3791 이후 계약
    경로 #3795 (CLOSED) / #3791 (MERGED) - 같은 결함의 본진. 이 이슈는 2.42.0 증거 추가
    경로 설치본 2.42.0 vs dev 2.48.0 - 현재 tip 회귀로 취급하면 안 됨
    경로 #3996 - Pool cooldown/caller main. 이 이슈와 원인 다름

    메인테이너의 판단이 필요한 지점

    • 중복으로 바로 닫을지, “2.42 증거 / fixed in 2.46+” 코멘트만 남기고 닫을지
    • 신고자에게 2.46+ 또는 현재 2.48.0으로 올리라고 안내할지

    너의 추천
    중복으로 닫으세요. 본문에 Landed via #3791 / fixed since v2.46.0 (및 현재 dev 2.48.0)을 남기고, 최신 빌드에서 다시 보이면 #3795를 재오거나 새 이슈에 HEAD SHA를 붙여 달라고 하세요. 새 수정 PR은 받지 않는 편이 맞습니다.

    이 댓글은 grok-bot이 작성했습니다

  3. lidge-jun commented on Sep 8, 2026

    @lidge-jun
    Owner

    Closing as a duplicate of #3795 — the disposition you proposed yourself.

    The incomplete-terminal quota accounting defect was fixed by #3791 and shipped in v2.46.0; dev is
    now on the 2.49.0 line. Your evidence was captured on an installed 2.42.0, which predates that fix,
    so the 18 consecutive incomplete terminals without failover are the known pre-fix behavior rather
    than a separate defect.

    Thank you for the careful sanitized aggregation, and for being explicit about what the logs do and
    do not establish — particularly that they show recovery on main without proving what initiated the
    account change. That precision is why this could be dispositioned without further investigation.

    If you see the same streak on 2.46.0 or later, please open a fresh report with the ocx version and
    the usage rows. That would be a real regression rather than this one.

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 working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions