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
- Run codewhale auth set --provider xai.
- Or export XAI_API_KEY in the launching shell.
- Or add api_key under [providers.xai] in ~/.codewhale/config.toml.
- 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
- Persist the key via codewhale auth set --provider xai or [providers.xai] api_key.
- If you prefer OAuth, complete the device flow and set auth_mode = "oauth" so the OAuth guidance branch is used.
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
- SiliconFlow China API key not found. Get a key: {}. Run 'cod
- Moonshot/Kimi API key not found. Get a key: {}. Run 'codewha
- {} API key not found.{} Run 'codewhale auth set --provider {
- Ollama Cloud API key not found. Get a key: {}. Run 'codewhal
- Secret storage write failed for {slot}: {err}. Refusing to w
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/33aea36622f54acd.
Report an issue: GitHub.