You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Codex pool selects main account over higher-priority account until WebUI is opened #7896
The main account is always selected first, even when an additional Codex account with a 5-hour quota window has a higher selection priority. The configured priority only takes effect after opening the WebUI.
This forces users to open the dashboard several times a day to make account routing follow the saved priorities. Account selection should work automatically without requiring the dashboard to be opened.
Reproduction
Configure main + additional Codex accounts in Pool mode.
Give the additional account higher selection priority than the main account.
Use the proxy without opening the WebUI: the main account is selected instead of the higher-priority additional account.
Open the WebUI without changing settings or manually selecting an account.
The configured priority takes effect and the additional account is selected.
Version
2.93.0
Operating system
Ubuntu 24.04 LTS
Logs or error output
Not collected yet; observed through account selection and quota usage.
Screenshots and supporting files
Possibly related: #6692, #605, #504. Not confirmed duplicates.
Redacted configuration
Pool mode; main + additional Codex accounts; the additional account has a higher selection priority and a 5-hour quota window.
Checks
I searched existing issues and documentation.
I removed secrets, tokens, account details, request credentials, and personal data.
Keeping this open; opening the dashboard correlating with a different selected account is not enough to identify the cause. Saved priority, eligibility/freshness of quota and refresh state, and an existing conversation binding can affect the candidate set separately. I have not reproduced this against an account pool.
Please capture two small redacted snapshots for the same model and conversation before/after opening the dashboard: OCX/Bun version, Pool/Direct mode, relative priority order, which rows are enabled/paused, whether each row's quota is known or stale, and the selected attempt's closed affinity / affinityReason fields when present. Use labels such as A/B rather than account ids; omit credentials, headers, emails, prompts and the real conversation id. Say whether opening the page triggered a refresh and whether the request used an explicit pin/manual preference. Do not change any of these while comparing.
Current dev includes #7883, which adds main-pool affinity diagnostics only; it is not a selection-priority fix and does not establish this report as resolved. No live account, priority or service state was changed in this triage.
Codex collected the following evidence directly from the local configuration, persisted usage/quota history, and the running proxy's health endpoint. The user delegated collection and posting to Codex.
Running OCX: 2.93.0; configured service Bun: 1.4.4; Ubuntu 24.04 LTS.
Current saved configuration: Pool mode, A = main (priority 0), B = additional account (priority 1). Neither is paused. B's switching threshold is 97%. Priority failback is unset/default off; cache affinity is default on. No explicit pin setting was found.
Historical sequence, 2026-10-29 UTC:
Time
Observation
01:24:41
Last retained WHAM observation of B before recovery: 5-hour usage 100%.
03:38:29
Reset time recorded for that window.
Between reset and recovery observation
298 requests on the unsuffixed openai route, including 246 HTTP 200 responses.
13:04:13.537
Next retained WHAM observation reports B at 0%.
13:04:26.763
First subsequent B request; affinity=new_bind, affinityReason=healthy (HTTP 499).
13:04:51.219
B request succeeds with HTTP 200 and the same affinity fields.
The requests immediately before and after the refresh use the same model (gpt-6-astra) and the same persisted conversation identifier, anonymized as C1. The last pre-refresh C1 request was at 13:04:06.082, HTTP 200, with no persisted affinity or affinityReason.
Limitations: These are reconstructed historical observations, not controlled before/after snapshots. The dashboard opening time and the trigger for the WHAM refresh were not recorded. Current configuration does not establish historical pin/config state. The unsuffixed openai route alone does not prove the credential identity of every request.
Main-route affinity fields are absent in the relevant records. Installed request preparation copies affinity diagnostics only for kind === "pool", consistent with the diagnostic gap addressed by #7883. This evidence supports investigating recovery-state freshness but does not establish a root cause or rule out conversation binding effects.
No account settings were changed, no service was restarted, and no dashboard/account-refresh API or synthetic inference request was invoked during collection. Credentials, account identifiers, real conversation identifiers, and prompt contents are omitted.
Fix for the scoring defect behind this report is merged into dev through #7994, as 0c74947.
Cause: when an account's weekly or monthly usage was known, the pool usage score still counted its last 5-hour reading after that window's reset time had passed. A higher-priority account that hit 100% on its 5-hour window therefore stayed above the switch threshold (97% in your config) until something re-read its usage from WHAM. Ordinary traffic does not re-read a non-selected account unless priority failback is on, and opening the dashboard does. That matches your timeline: B's reset was recorded at 03:38, and B came back right after the 13:04 usage read. After the fix, a known reset that has passed no longer counts against the account, so B is selected again as soon as its reset time passes. A missing or invalid reset still counts as blocking.
Keeping this open until you can confirm on a build that includes #7994. Other things can still keep a conversation on main, such as cache affinity for an existing conversation (priority failback is off by default). If it still happens, the redacted snapshot @Ingwannu described earlier will tell those apart.
Activity
Ingwannu commentedon Oct 29, 2026
Keeping this open; opening the dashboard correlating with a different selected account is not enough to identify the cause. Saved priority, eligibility/freshness of quota and refresh state, and an existing conversation binding can affect the candidate set separately. I have not reproduced this against an account pool.
Please capture two small redacted snapshots for the same model and conversation before/after opening the dashboard: OCX/Bun version, Pool/Direct mode, relative priority order, which rows are enabled/paused, whether each row's quota is known or stale, and the selected attempt's closed
affinity/affinityReasonfields when present. Use labels such as A/B rather than account ids; omit credentials, headers, emails, prompts and the real conversation id. Say whether opening the page triggered a refresh and whether the request used an explicit pin/manual preference. Do not change any of these while comparing.Current dev includes #7883, which adds main-pool affinity diagnostics only; it is not a selection-priority fix and does not establish this report as resolved. No live account, priority or service state was changed in this triage.
jhooc77 commentedon Oct 29, 2026
Codex collected the following evidence directly from the local configuration, persisted usage/quota history, and the running proxy's health endpoint. The user delegated collection and posting to Codex.
Historical sequence, 2026-10-29 UTC:
openairoute, including 246 HTTP 200 responses.affinity=new_bind,affinityReason=healthy(HTTP 499).The requests immediately before and after the refresh use the same model (
gpt-6-astra) and the same persisted conversation identifier, anonymized as C1. The last pre-refresh C1 request was at 13:04:06.082, HTTP 200, with no persistedaffinityoraffinityReason.Limitations: These are reconstructed historical observations, not controlled before/after snapshots. The dashboard opening time and the trigger for the WHAM refresh were not recorded. Current configuration does not establish historical pin/config state. The unsuffixed
openairoute alone does not prove the credential identity of every request.Main-route affinity fields are absent in the relevant records. Installed request preparation copies affinity diagnostics only for
kind === "pool", consistent with the diagnostic gap addressed by #7883. This evidence supports investigating recovery-state freshness but does not establish a root cause or rule out conversation binding effects.No account settings were changed, no service was restarted, and no dashboard/account-refresh API or synthetic inference request was invoked during collection. Credentials, account identifiers, real conversation identifiers, and prompt contents are omitted.
fix(codex): stop scoring an elapsed 5-hour window against a pool acco…
lidge-jun commentedon Oct 30, 2026
Fix for the scoring defect behind this report is merged into
devthrough #7994, as 0c74947.Cause: when an account's weekly or monthly usage was known, the pool usage score still counted its last 5-hour reading after that window's reset time had passed. A higher-priority account that hit 100% on its 5-hour window therefore stayed above the switch threshold (97% in your config) until something re-read its usage from WHAM. Ordinary traffic does not re-read a non-selected account unless priority failback is on, and opening the dashboard does. That matches your timeline: B's reset was recorded at 03:38, and B came back right after the 13:04 usage read. After the fix, a known reset that has passed no longer counts against the account, so B is selected again as soon as its reset time passes. A missing or invalid reset still counts as blocking.
Keeping this open until you can confirm on a build that includes #7994. Other things can still keep a conversation on main, such as cache affinity for an existing conversation (priority failback is off by default). If it still happens, the redacted snapshot @Ingwannu described earlier will tell those apart.