Skip to content

[Feature]: keep Free-tier ChatGPT accounts out of Codex pool selection #4211

Description

@lidge-jun

Area

Authentication and account pool

What are you trying to accomplish?

I run a Codex account pool built from several paid ChatGPT accounts. When one subscription lapses and the account is downgraded to Free, I want pool selection to stop handing it production traffic, instead of discovering the downgrade from failed or degraded requests.

Reported on X by @LjranceLi on 2026-09-10: one of their accounts expired without being renewed, was downgraded to Free, and they asked for "an option to only select non-free accounts" for GPT subscribers (https://x.com/LjranceLi/status/2097934784895058054).

What prevents this today?

Pool eligibility never looks at the plan tier. In src/codex/account-usability.ts at dev 6d3ad12e3 (2.51.0), isCodexAccountUsable() decides selection from an optional modelEligibleAccountIds set for account-gated models, the main-account hard lock / native-main traffic block / legacy pool sentinel, isAccountNeedsReauth(), pool membership, a stored credential, deletedAt, and codexValidationPending. The plan is not an input to any branch.

The tier is already known locally:

  • src/codex/plan-from-token.ts persists the JWT chatgpt_plan_type onto codexAccounts[].plan when it contradicts the stored value.
  • src/codex/plan.ts classifies plan keys and already treats go and free specially (isThirtyDayOnlyCodexPlan).
  • src/codex/main-account.ts documents the main-account plan label (plus, go, free, team).

The only exclusion mechanism is manual and untyped: src/codex/account-pause.ts writes pausedCodexAccountIds, which an operator has to set by hand after they have already diagnosed the failure.

What should OpenCodex do?

  1. Let an operator declare a plan policy for pool selection, so a Free (or otherwise below-threshold) account is skipped for ordinary routing.
  2. When a refresh observes that an account's plan dropped below the policy, stop selecting it and record a reason that names the plan change, instead of leaving it in rotation to fail per request.
  3. Show that reason where the operator already looks: the account card in the dashboard and the account line in CLI status output, with the plan label visible.
  4. Keep an explicit, operator-chosen route to that account working. This is a selection policy, not a hard block.

Example usage or interface

# opt in: never auto-select a downgraded account
ocx config set codexPool.excludedPlans '["free"]'

# or, expressed as a floor
ocx config set codexPool.minimumPlan plus

Dashboard, Providers -> Codex account card:

account: work@example.com   plan: free   state: not selected (plan below codexPool.minimumPlan=plus)

Alternatives or workarounds

  • Manually pause the account (pausedCodexAccountIds). That works only after the operator has already diagnosed which account regressed.
  • Delete and re-add the account after renewal. Same diagnosis cost, and it discards affinity and quota history.

Additional context

Checks

  • I searched existing issues and documentation.
  • This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
  • I removed secrets and personal data.

Activity

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, plansenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions