Skip to content

[Bug]: Codex pool selects main account over higher-priority account until WebUI is opened #7896

Closed

Description

@jhooc77

Client or integration

Other — Codex client through OpenCodex proxy

Area

Authentication and account pool

Summary

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

  1. Configure main + additional Codex accounts in Pool mode.
  2. Give the additional account higher selection priority than the main account.
  3. Use the proxy without opening the WebUI: the main account is selected instead of the higher-priority additional account.
  4. Open the WebUI without changing settings or manually selecting an account.
  5. 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.

Activity

  1. added
    bugSomething isn't working
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    on Oct 28, 2026
  2. Ingwannu commented on Oct 29, 2026

    @Ingwannu
    Owner

    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.

  3. jhooc77 commented on Oct 29, 2026

    @jhooc77
    Author

    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.

  4. lidge-jun commented on Oct 30, 2026

    @lidge-jun
    Owner

    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.

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