Hmbown/CodeWhale · 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 TUI/config layer refuses to start a session for the xAI provider because no API key (or OAuth credential) can be found. The library checks the provider config entry for xAI OAuth usage and codewhale's OAuth credential store; if neither has tokens and no static API key is configured, it bails with setup instructions. It exists to fail loud at load rather than let a request go out unauthenticated.
Solutions
- Run `codewhale auth set --provider xai` and paste an API key from https://console.x.ai/
- Set the XAI_API_KEY environment variable in your shell/CI environment
- Add `api_key = "xai-..."` under [providers.xai] in ~/.codewhale/config.toml
- Or run `codewhale auth xai-device` for OAuth and set auth_mode = "oauth" under [providers.xai]
Example fix
// before (config.toml) [providers.xai] // after [providers.xai] api_key = "xai-your-key-here" # or: auth_mode = "oauth"
Defensive patterns
Strategy: validation
Validate before calling
let ok = std::env::var("XAI_API_KEY").map(|v| !v.trim().is_empty()).unwrap_or(false);
if !ok { eprintln!("xAI key missing: run `codewhale auth set --provider xai` or set XAI_API_KEY"); }
else { /* proceed */ } Try / catch
match result {
Err(e) if e.to_string().contains("xAI API key not found") => configure_xai_auth_and_retry(),
other => other?,
} Prevention
- Provision keys via `codewhale auth set` once per machine
- Keep XAI_API_KEY in your shell profile or secret manager
- In CI, inject the key as a secret env var
When it happens
Trigger: Selecting/using provider `xai` when: no XAI_API_KEY env var, no [providers.xai] api_key in ~/.codewhale/config.toml, no stored OAuth tokens for Xai, and the provider config is not flagged auth_mode="oauth" with existing tokens.
Common situations: Fresh install without `codewhale auth set --provider xai`; CI/container where XAI_API_KEY is unset; user deleted or renamed the config table; switching machines without migrating ~/.codewhale credentials.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- Ollama Cloud API key not found. Get a key
- api_key cannot be empty string
- Codewhale-owned xAI OAuth credentials are inactive until…
- {}
- Custom provider ' ' API key not found. Set the environment…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/33aea36622f54acd.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/config.rs:7405
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(crate::oauth::OAuthProvider::Chatgpt)
),
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::oauth::credentials_present(crate::oauth::OAuthProvider::Xai, self)
{
anyhow::bail!(
"{}",
crate::oauth::missing_auth_message(crate::oauth::OAuthProvider::Xai)
);
}
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,View on GitHub (pinned to 73e0f67d83)