Skip to content

Pool mode should retry another account after an account-specific unsupported-model response #335

Description

@ropepop

Summary

In Codex account Pool mode, an account-specific unsupported-model HTTP 400 ends the request immediately even when another configured account can use the requested model.

The paid main account is not missing access to gpt-5.6-sol, and account switching is not persistently stuck. Controlled testing showed that manually selecting the main account fixed the same visible Codex thread immediately, without restarting Codex. The remaining reproducible problem is the lack of bounded failover after the first pooled account rejects the model.

This is distinct from #297: the model catalog is correct and Sol exposes the expected reasoning levels. The failure occurs during pooled request routing.

Environment

  • OpenCodeX 2.7.35
  • Canonical OpenAI provider in Pool mode
  • Main ChatGPT Pro account plus a secondary pooled account
  • Model: gpt-5.6-sol

Confirmed behavior

With the secondary account selected, the existing Codex app thread produced an account-specific rejection:

13:08:16Z  secondary route  gpt-5.6-sol  400
13:08:26Z  secondary route  gpt-5.6-sol  400

Upstream response:

{"detail":"The 'gpt-5.6-sol' model is not supported when using Codex with a ChatGPT account."}

OpenCodeX returned that response directly. It did not retry the main paid account.

The active Pool account was then changed to __main__ while the same visible Codex thread remained open. The next Sol request succeeded before any restart:

13:09:07Z  main route  gpt-5.6-sol  200

Codex was then fully quit and relaunched while the OpenCodeX proxy remained running. After reopening the original troubleshooting thread, Sol still succeeded:

13:12:47Z  main route  gpt-5.6-sol  200

What this rules out

The controlled test does not support these earlier hypotheses:

  • the paid main account lacks Sol access;
  • changing the active account remains stuck;
  • restarting Codex is required for the account change to take effect;
  • the model catalog or reasoning-level clamp causes this request failure.

Actual problem

OpenCodeX classifies generic 4xx responses as caller failures. That is appropriate for ordinary malformed requests, but this particular response describes an account/model capability mismatch. Pool mode therefore has another potentially eligible account but does not try it.

Diagnostics also make this harder to understand than necessary: request history exposes provider-style route labels, but not a clear dedicated field for the effective pooled account and thread affinity decision.

Expected behavior

For this narrow unsupported-model response, Pool mode should treat the failure as account-specific and retry once with another eligible account. Unrelated HTTP 400 responses should remain non-retryable.

A bounded implementation could:

  1. detect the upstream unsupported-model response without broadening generic 400 retry behavior;
  2. clear or reconsider the request's account affinity;
  3. rebuild authentication for another pooled account and retry once;
  4. stop after one bounded pass when no account supports the model;
  5. expose the effective pooled account/affinity decision in sanitized diagnostics.

Suggested regression coverage

  • unsupported-model 400 from account A retries account B and succeeds;
  • unrelated 400 remains non-retryable;
  • retry is bounded when every account rejects the model;
  • the request log identifies the effective pooled account without exposing credentials;
  • manual selection of __main__ continues to route a fresh request through the main account.

Related: #297, #186, and #205.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions