Client or integration
Codex App
Area
Authentication and account pool
Summary
OpenCodex 2.41.0 continued routing new Codex requests to a ChatGPT pool account after its five-hour window reached 100%, although auto-switch was enabled at an 80% threshold and a second account had only 3% usage. Requests recovered immediately after the exhausted account was manually paused.
This appears to be a recurrence or remaining transport-path gap related to #3029, #3110, and #3176, rather than a missing auto-switch setting.
Reproduction
- Install and start
@bitkyc08/opencodex 2.41.0 with two valid ChatGPT accounts in the Codex account pool.
- In the OpenCodex dashboard, enable automatic account switching, select the
quota strategy, set the threshold to 80%, and set the sticky request limit to 1.
- Use account A until the dashboard quota refresh shows its five-hour/short window at 100%. Confirm account B remains available; in this occurrence it showed 3% five-hour usage.
- With account A still active, submit new streaming turns from the Codex App through OpenCodex. Multiple concurrent and sequential turns were active during the occurrence.
- Observe that new requests continue selecting account A and fail with HTTP 502 instead of switching to account B. In the local usage log, each failed attempt had
sendCount: 1 and an empty recoveryKinds array.
- In the OpenCodex dashboard, manually pause account A.
- Submit another Codex turn. The next recorded request selects account B and returns HTTP 200.
Observed timeline on 2026-09-04 KST: account A produced 118 HTTP 502 attempts from 10:58:32 through 11:21:11. Account B returned HTTP 200 at 11:21:33, immediately after account A was manually paused.
Version
2.41.0
Operating system
Windows NT 10.0.26200.0
Provider and model
OpenAI ChatGPT account pool / Codex models used by Codex App
Logs or error output
Sanitized usage.jsonl aggregation, 2026-09-04 KST
provider/account: exhausted pool account (identifier removed)
HTTP 502 attempts: 118
first: 10:58:32
last: 11:21:11
sendCount min/max: 1/1
attempts with recoveryKinds: 0
attempts with streamAborted=true: 55
attempts with firstOutputMs: 52
attempts without streamAborted marker: 63
attempts with persisted upstreamError: 0
After manually pausing the exhausted account:
healthy pool account HTTP 200: 11:21:33
The subsequent quota refresh showed account A at five-hour/short 100% and weekly 49%, while account B was at five-hour/short 3% and weekly 18%.
The exact upstream 502 response body was not persisted. Therefore, this report does not claim that every unmarked 502 contained the canonical quota message.
Screenshots and supporting files
No screenshot is attached. The values above were aggregated directly from the local OpenCodex usage log with account identifiers, prompts, tokens, and response content excluded.
Relevant prior work: #3029 reported the same manual-pause recovery symptom; #3110 treated a live full burst window as exhausted; #3176 added rotation for quota messages wrapped in HTTP 502; #585 added same-request failover for pre-stream 429/402 responses.
The 2.41.0 main source at 4600f80198c8eb6cef1b9cf1338d51906100007e contains the bounded pre-stream 5xx quota-message classifier. It also explicitly leaves a quota failure terminal after SSE begins and records post-200 stream failure as synthetic HTTP 502 with streamAborted.
Suggested regression coverage:
- Account A has
shortPercent: 100, account B is healthy, quota threshold is 80%, and multiple new/concurrent requests are admitted.
- A post-200
streamAborted request may remain terminal, but subsequent new admissions must avoid account A.
- A 502 without a persisted canonical message must not override a fresh quota snapshot that already marks account A at 100%.
- Affinity is cleared or re-evaluated so the next request reaches account B.
Redacted configuration
{
"accountPool": {
"accounts": 2,
"autoSwitch": true,
"strategy": "quota",
"thresholdPercent": 80,
"stickyRequestLimit": 1
}
}
The JSON above is a redacted description of the effective dashboard settings, not a verbatim copy of the on-disk configuration schema.
Checks
This issue or PR was generated by LazyCodex.
Tag: lazycodex-generated
Client or integration
Codex App
Area
Authentication and account pool
Summary
OpenCodex 2.41.0 continued routing new Codex requests to a ChatGPT pool account after its five-hour window reached 100%, although auto-switch was enabled at an 80% threshold and a second account had only 3% usage. Requests recovered immediately after the exhausted account was manually paused.
This appears to be a recurrence or remaining transport-path gap related to #3029, #3110, and #3176, rather than a missing auto-switch setting.
Reproduction
@bitkyc08/opencodex2.41.0 with two valid ChatGPT accounts in the Codex account pool.quotastrategy, set the threshold to 80%, and set the sticky request limit to 1.sendCount: 1and an emptyrecoveryKindsarray.Observed timeline on 2026-09-04 KST: account A produced 118 HTTP 502 attempts from 10:58:32 through 11:21:11. Account B returned HTTP 200 at 11:21:33, immediately after account A was manually paused.
Version
2.41.0
Operating system
Windows NT 10.0.26200.0
Provider and model
OpenAI ChatGPT account pool / Codex models used by Codex App
Logs or error output
The subsequent quota refresh showed account A at five-hour/short 100% and weekly 49%, while account B was at five-hour/short 3% and weekly 18%.
The exact upstream 502 response body was not persisted. Therefore, this report does not claim that every unmarked 502 contained the canonical quota message.
Screenshots and supporting files
No screenshot is attached. The values above were aggregated directly from the local OpenCodex usage log with account identifiers, prompts, tokens, and response content excluded.
Relevant prior work: #3029 reported the same manual-pause recovery symptom; #3110 treated a live full burst window as exhausted; #3176 added rotation for quota messages wrapped in HTTP 502; #585 added same-request failover for pre-stream 429/402 responses.
The 2.41.0
mainsource at4600f80198c8eb6cef1b9cf1338d51906100007econtains the bounded pre-stream 5xx quota-message classifier. It also explicitly leaves a quota failure terminal after SSE begins and records post-200 stream failure as synthetic HTTP 502 withstreamAborted.Suggested regression coverage:
shortPercent: 100, account B is healthy, quota threshold is 80%, and multiple new/concurrent requests are admitted.streamAbortedrequest may remain terminal, but subsequent new admissions must avoid account A.Redacted configuration
{ "accountPool": { "accounts": 2, "autoSwitch": true, "strategy": "quota", "thresholdPercent": 80, "stickyRequestLimit": 1 } }The JSON above is a redacted description of the effective dashboard settings, not a verbatim copy of the on-disk configuration schema.
Checks
This issue or PR was generated by LazyCodex.
Tag: lazycodex-generated