Hmbown/CodeWhale · error · anyhow::Error

xAI API key not found. Get a key: https://console.x.ai/ Run

Error message

xAI API key not found. Get a key: https://console.x.ai/
Run 'codewhale auth set --provider xai', set XAI_API_KEY, or add [providers.xai] api_key.
OAuth alternative: run `codewhale auth xai-device` for Codewhale-owned storage and set [providers.xai] auth_mode = "oauth".

What it means

The default xAI branch: auth_mode is not oauth and no Grok CLI tokens are on disk, so plain API-key guidance is shown — get a key from console.x.ai, persist it via auth set / XAI_API_KEY / [providers.xai] api_key, with the OAuth alternative (codewhale auth xai-device plus auth_mode = "oauth") as the last option.

Source

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

            }
            ApiProvider::Anthropic | ApiProvider::Openmodel => {
                anyhow::bail!("{}", missing_provider_api_key_message(provider)?)
            }
            ApiProvider::OpencodeZen => {
                anyhow::bail!("{}", missing_provider_api_key_message(provider)?)
            }
            ApiProvider::OpenaiCodex => anyhow::bail!("{}", crate::oauth::missing_auth_message()),
            ApiProvider::Xai => {
                // Prefer OAuth guidance when auth_mode requests it or Grok CLI
                // tokens already exist; otherwise show both API-key and OAuth.
                if self
                    .provider_config_for(provider)
                    .is_some_and(provider_config_uses_xai_oauth)
                    || crate::xai_oauth::credentials_present(self)
                {
                    anyhow::bail!("{}", crate::xai_oauth::missing_auth_message());
                }
                anyhow::bail!(
                    "xAI API key not found. Get a key: https://console.x.ai/\n\
                     Run 'codewhale auth set --provider xai', set XAI_API_KEY, or add \
                     [providers.xai] api_key.\n\
                     OAuth alternative: run `codewhale auth xai-device` for \
                     Codewhale-owned storage and set [providers.xai] auth_mode = \"oauth\"."
                );
            }
            // Self-hosted deployments commonly run without auth on localhost.
            // Return an empty key and let the client omit the Authorization header.
            ApiProvider::Sglang | ApiProvider::Vllm => Ok(String::new()),
            ApiProvider::Ollama
                if provider_route_is_keyless_self_hosted(provider, &self.deepseek_base_url()) =>
            {
                Ok(String::new())
            }
            ApiProvider::Ollama => {
                let help = credential_help_for_provider_route(provider, &self.deepseek_base_url());
                anyhow::bail!(

View on GitHub (pinned to 8880682c63)

Solutions

  1. Run codewhale auth set --provider xai.
  2. Or export XAI_API_KEY in the launching shell.
  3. Or add api_key under [providers.xai] in ~/.codewhale/config.toml.
  4. For OAuth instead: codewhale auth xai-device and set [providers.xai] auth_mode = "oauth".

Example fix

# before
provider = "xai"
# no credentials

# after (terminal)
# codewhale auth set --provider xai
# or: export XAI_API_KEY=xai-...
Defensive patterns

Strategy: validation

Validate before calling

fn xai_key_present(cfg: &Config) -> bool {
    env_nonempty("XAI_API_KEY")
        || cfg.provider_config_for(ApiProvider::Xai)
            .and_then(|pc| pc.api_key)
            .is_some_and(|k| !k.trim().is_empty())
        || secret_store_has(ApiProvider::Xai)
}

anyhow::ensure!(xai_key_present(&config), "configure xAI auth (key or OAuth) first");

Type guard

fn xai_credentials_configured(cfg: &Config) -> bool {
    xai_key_present(cfg) || xai_oauth_ready(cfg)
}

Try / catch

match config.deepseek_api_key() {
    Err(e) if e.to_string().starts_with("xAI API key not found") => {
        run_auth_set(ApiProvider::Xai)?; // or guide to codewhale auth xai-device
        config.deepseek_api_key()
    }
    other => other,
}

Prevention

When it happens

Trigger: provider = xai with no secret-store key, no XAI_API_KEY, no [providers.xai] api_key, and no OAuth path selected.

Common situations: First-time xAI/Grok usage; keys wiped by logout; env var missing in non-interactive shells.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/33aea36622f54acd. Report an issue: GitHub.