Model-specific 401/403 triggers unnecessary auth recovery and surfaces as generic Other
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.903.9818.0 (core 0.153.4)
What subscription do you have?
ChatGPT Pro
What platform is your computer?
Microsoft Windows NT 10.0.19045.0 x64
What issue are you seeing?
Codex Desktop treats a model-entitlement 401 as a recoverable authentication failure, retries/falls back between transports, refreshes authentication, and finally reports a generic error.
Observed backend error:
401 Unauthorized: You are not authorized to access this model.
The authentication itself is valid: gpt-5.6-sol succeeds in the same refreshed ChatGPT session, while gpt-daybreak-blue-latest alone fails. The alias failure takes roughly 38–43 seconds because recovery/fallback work occurs even though the server response is model-specific.
A controlled gpt-5.6-sol A/B test also showed that an explicit cyberAccessProgram=daybreakBlue request returns:
403 Forbidden: The requested Cyber access program is not authorized for this workspace.
That deterministic authorization failure was also retried across WebSocket/HTTP for 23.380 seconds and ultimately surfaced as generic codexErrorInfo: other.
The Daybreak alias/catalog entitlement symptom is tracked in #44566. This issue is specifically about retry classification and the final user-facing error type.
What steps can reproduce the bug?
Model-specific 401
- Sign in to Codex Desktop using ChatGPT authentication.
- Select
gpt-daybreak-blue-latest. - Send a harmless prompt.
- Observe the model-specific HTTP 401.
- Observe repeated recovery/fallback activity and the delayed generic final error.
- Select
gpt-5.6-solin the same refreshed session and send the same prompt; it succeeds.
Workspace-specific 403
Using two new app-server threads with the same ChatGPT authentication, same gpt-5.6-sol model, low reasoning effort, and harmless exact-response prompts:
cyberAccessProgram=standard: completed in 2.551 seconds.cyberAccessProgram=daybreakBlue: deterministic workspace-authorization 403 after 23.380 seconds, following transport retries.
No API key was used.
What is the expected behavior?
Authorization failures whose messages identify a model or workspace program should be treated as fatal, non-retryable entitlement errors.
Expected behavior:
- Do not refresh ChatGPT authentication for
You are not authorized to access this model. - Do not retry or switch transports for
The requested Cyber access program is not authorized for this workspace. - Surface a typed actionable error such as
ModelNotAuthorizedorCyberProgramNotAuthorized. - Tell the user that API-project access and the ChatGPT Codex workspace entitlement may differ.
- Reserve
Unauthorizedauthentication recovery for invalid or expired credentials.
Additional information
Public-code observations at commit 94697375cb9d2aa8ae74d61957c6b396819bec94:
codex-rs/model-provider/src/provider.rs:195-199classifies every HTTP 401 as a recoverable auth error without considering a model-specific denial message:
https://github.com/openai/codex/blob/94697375cb9d2aa8ae74d61957c6b396819bec94/codex-rs/model-provider/src/provider.rs#L195-L199codex-rs/protocol/src/error.rs:456-464maps refresh-token failure toUnauthorized, while unmatched errors fall through toOther:
https://github.com/openai/codex/blob/94697375cb9d2aa8ae74d61957c6b396819bec94/codex-rs/protocol/src/error.rs#L456-L464
Potential approach:
- Inspect the structured backend error code/message before entering authentication recovery.
- Add explicit non-retryable entitlement variants for model and cyber-program authorization failures.
- Preserve these variants through transport fallback and protocol error mapping.
- Add regression tests proving that these 401/403 cases make one backend attempt and retain an actionable final error.
Related: #44566
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex-rs/model-provider/src/provider.rs:195-199 to trace 401 classification, then read codex-rs/protocol/src/error.rs:456-464 for final error mapping. Add regression coverage for the model-specific 401 and workspace-specific 403, verifying that each makes one backend attempt, skips authentication and transport recovery, and reaches an actionable typed error rather than Other.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- authentication, backend-api-design, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100