Area
Authentication and account pool
What are you trying to accomplish?
Re-authenticate a Codex pool account that has expired or dropped its session (e.g., token revoked, session expired), so that the account becomes usable again without having to delete it from the pool first.
What prevents this today?
When a pool account expires and the operator tries to log in again via the WebUI (or CLI) using the same account credentials, checkAccountIdCollision (src/codex/auth-collision.ts) sees that the chatgptAccountId already exists in the pool config and rejects the login attempt with:
Account is already in the pool (chatgpt-...)
The only workaround today is a destructive 2-step process:
- Delete the expired account from the pool.
- Re-add it via a fresh login.
This destroys the account's usage history, quota recovery state, manually configured priority/strategy settings, and pool labels.
What should OpenCodex do?
When a login flow completes and checkAccountIdCollision detects that the account already exists in the pool, it should check if the existing pool account's session is expired, invalid, or being explicitly re-authenticated. Instead of aborting the flow with a collision error, OpenCodex should update the existing account in-place with the new credential/tokens, preserving its id, usage history, and configuration.
If an operator explicitly clicks "Re-authenticate" (or runs an equivalent CLI command), the collision check should be bypassed entirely for that specific account ID, or the merge logic should just overwrite the token material.
Example usage or interface
- Dashboard shows a pool account as
Expired / Needs re-authentication.
- Operator clicks "Re-authenticate" on that account card.
- OAuth/Device flow completes.
- Instead of
Account is already in the pool error, the UI says Account re-authenticated successfully and the token is updated. History and routing settings remain intact.
Alternatives or workarounds
- Deleting the account and re-adding it — loses all historical usage data, manual aliases, and pool configuration.
- Manually editing
auth.json / config.json on the filesystem — error-prone and defeats the purpose of the management API.
Additional context
Checks
Area
Authentication and account pool
What are you trying to accomplish?
Re-authenticate a Codex pool account that has expired or dropped its session (e.g., token revoked, session expired), so that the account becomes usable again without having to delete it from the pool first.
What prevents this today?
When a pool account expires and the operator tries to log in again via the WebUI (or CLI) using the same account credentials,
checkAccountIdCollision(src/codex/auth-collision.ts) sees that thechatgptAccountIdalready exists in the pool config and rejects the login attempt with:The only workaround today is a destructive 2-step process:
This destroys the account's usage history, quota recovery state, manually configured priority/strategy settings, and pool labels.
What should OpenCodex do?
When a login flow completes and
checkAccountIdCollisiondetects that the account already exists in the pool, it should check if the existing pool account's session is expired, invalid, or being explicitly re-authenticated. Instead of aborting the flow with a collision error, OpenCodex should update the existing account in-place with the new credential/tokens, preserving itsid, usage history, and configuration.If an operator explicitly clicks "Re-authenticate" (or runs an equivalent CLI command), the collision check should be bypassed entirely for that specific account ID, or the merge logic should just overwrite the token material.
Example usage or interface
Expired/Needs re-authentication.Account is already in the poolerror, the UI saysAccount re-authenticated successfullyand the token is updated. History and routing settings remain intact.Alternatives or workarounds
auth.json/config.jsonon the filesystem — error-prone and defeats the purpose of the management API.Additional context
src/codex/auth-collision.ts: checkAccountIdCollision()is where the hard block occurs today.Checks