Hmbown/CodeWhale · error · anyhow::Error
xAI OAuth credentials not found. Options: 1. Run `codewhale
Error message
xAI OAuth credentials not found.
Options:
1. Run `codewhale auth xai-device` for Codewhale-owned OAuth storage
2. To read an existing Grok CLI login without changing it, run `codewhale auth external-consent --provider xai --mode read-only --path {}`
3. Or use API-key auth: export XAI_API_KEY=... / codewhale auth set --provider xai What it means
Emitted from xai_oauth::missing_auth_message() (crates/tui/src/xai_oauth.rs:776) when xAI auth_mode = "oauth" (or Grok CLI tokens exist) but no usable OAuth credential is found: no Codewhale-owned device-login storage and no read-only consent for the Grok CLI auth file (its path is interpolated). It offers three exits: the Codewhale-owned device flow, read-only reuse of a Grok CLI login, or plain API-key auth.
Source
Thrown at crates/tui/src/config.rs:6418
provider_config_table_name(provider)?
);
}
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 => {View on GitHub (pinned to 8880682c63)
Solutions
- Run codewhale auth xai-device to create Codewhale-owned OAuth storage.
- Or grant read-only reuse of the existing Grok CLI login: codewhale auth external-consent --provider xai --mode read-only --path <path from message>.
- Or fall back to API keys: export XAI_API_KEY=... or codewhale auth set --provider xai.
Example fix
# before [providers.xai] auth_mode = "oauth" # device flow never completed # after (terminal) # codewhale auth xai-device # or: codewhale auth external-consent --provider xai --mode read-only --path ~/.grok/auth.json
Defensive patterns
Strategy: fallback
Validate before calling
fn xai_oauth_ready(config: &Config) -> bool {
crate::xai_oauth::credentials_present(config) // Codewhale-owned storage or consented Grok file
|| config
.provider_config_for(ApiProvider::Xai)
.is_some_and(provider_config_uses_xai_oauth)
&& crate::xai_oauth::credentials_present(config)
}
if !xai_oauth_ready(&config) && !env_nonempty("XAI_API_KEY") {
// fall back to API-key route or prompt `codewhale auth xai-device`
} Type guard
fn xai_auth_path_available(config: &Config) -> bool {
xai_oauth_ready(config) || env_nonempty("XAI_API_KEY")
} Try / catch
match config.deepseek_api_key() {
Err(e) if e.to_string().starts_with("xAI OAuth credentials not found") => {
// fall back to API-key auth: export XAI_API_KEY / codewhale auth set --provider xai,
// or complete `codewhale auth xai-device` and retry
Err(e)
}
other => other,
} Prevention
- Finish `codewhale auth xai-device` before setting auth_mode = "oauth".
- Grok CLI logins are opt-in: grant external-consent to reuse them read-only.
- Keep an XAI_API_KEY fallback configured while setting up OAuth.
When it happens
Trigger: [providers.xai] auth_mode = "oauth" with the device flow never run; a Grok CLI login present at the interpolated path but external-consent never granted; OAuth storage cleared by logout.
Common situations: Switching xAI from API key to OAuth without completing `codewhale auth xai-device`; expecting Grok CLI logins to be picked up automatically (they are opt-in via consent).
Related errors
- OpenAI Codex OAuth credentials are unavailable. Codewhale c
- parallel(): expected an array of thunks
- The Codewhale service returned a verification URL without a
- Codewhale-owned xAI OAuth file {} is not valid UTF-8
- external credential access for {} is dormant until that prov
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/92ca64539da91854.
Report an issue: GitHub.