Hmbown/CodeWhale · error

Codex OAuth credentials are only available on the official…

Error message

Codex OAuth credentials are only available on the official OpenAI Codex route

What it means

`codex_credentials()` only hands out Codex OAuth credentials when the active provider is the official OpenAI Codex route with the default endpoint (or when credentials come from the environment). Any other provider or a custom Codex endpoint is rejected to avoid pairing identities across an owner refresh or a hostile endpoint swap.

Solutions

  1. Switch the active provider back to the official OpenAI Codex route and remove any custom endpoint override for it
  2. If credentials should come from the environment, set the Codex OAuth env variables so `credentials_from_env()` succeeds
  3. Re-run `codex auth`/OAuth login while on the official route so valid credentials are stored
  4. Remove the custom `base_url` for the OpenaiCodex provider in the config file
Defensive patterns

Strategy: type-guard

Validate before calling

if config.api_provider() != ApiProvider::OpenaiCodex
    || config.provider_uses_custom_endpoint(ApiProvider::OpenaiCodex) {
    // route user back to official Codex route or use env credentials
}

Type guard

fn codex_credentials_available(c: &Config) -> bool {
    crate::oauth::credentials_from_env().is_some()
        || (c.api_provider() == ApiProvider::OpenaiCodex
            && !c.provider_uses_custom_endpoint(ApiProvider::OpenaiCodex))
}

Try / catch

match config.codex_credentials() {
    Err(e) if e.to_string().contains("only available on the official OpenAI Codex route") => {
        // switch provider or fall back to API-key auth
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `config.codex_credentials()` while `api_provider() != OpenaiCodex`, or while a custom base URL is configured for the OpenaiCodex provider, and `credentials_from_env()` returned nothing.

Common situations: User switched to another provider (Anthropic, custom endpoint) but code or a command still requests Codex OAuth credentials; user pointed the Codex provider at a proxy/gateway URL; stale config after migrating between providers.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/50c3a1f8b8a235b1. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/config.rs:12325

/// Check whether the given provider has any usable API key — via env var,
/// provider/root config. Used by the `/provider` picker to decide whether to
/// prompt for a key inline.
#[must_use]
pub fn has_api_key_for(config: &Config, provider: ApiProvider) -> bool {
    credential_resolve::resolve_credential_source(config, provider).is_present()
}

impl Config {
    /// Resolve one coherent Codex OAuth snapshot. The bearer and account id
    /// must come from the same secure file handle; opening the external JSON a
    /// second time could pair identities across an atomic owner refresh or a
    /// hostile path swap.
    pub(crate) fn codex_credentials(&self) -> Result<crate::oauth::CodexCredentials> {
        if let Some(credentials) = crate::oauth::credentials_from_env() {
            return Ok(credentials);
        }
        anyhow::ensure!(
            self.api_provider() == ApiProvider::OpenaiCodex
                && !self.provider_uses_custom_endpoint(ApiProvider::OpenaiCodex),
            "Codex OAuth credentials are only available on the official OpenAI Codex route"
        );
        if crate::oauth::credentials_valid(crate::oauth::OAuthProvider::Chatgpt, self) {
            let owned =
                crate::oauth::get_owned_credentials(crate::oauth::OAuthProvider::Chatgpt, self)?;
            return Ok(crate::oauth::CodexCredentials {
                access_token: owned.access_token,
                account_id: owned.account_id,
            });
        }
        let path = crate::oauth::auth_file_path();
        let grant = self.external_credential_read_grant(
            ApiProvider::OpenaiCodex,
            codewhale_config::ExternalCredentialSource::CodexCli,
            &path,
        )?;

View on GitHub (pinned to 73e0f67d83)