Hmbown/CodeWhale · error · anyhow::Error
Ollama Cloud API key not found. Get a key: {}. Run 'codewhal
Error message
Ollama Cloud API key not found. Get a key: {}. Run 'codewhale auth set --provider ollama', set OLLAMA_API_KEY, or add [providers.ollama] api_key in ~/.codewhale/config.toml. What it means
Ollama has two personalities: local self-hosted (keyless when the route is loopback/self-hosted, returning an empty key so the Authorization header is omitted) and Ollama Cloud. When the route is NOT keyless-self-hosted, this error demands a cloud key via auth set, OLLAMA_API_KEY, or [providers.ollama] api_key, with the cloud console URL interpolated (defaulting to OLLAMA_CLOUD_API_KEY_URL).
Source
Thrown at crates/tui/src/config.rs:6438
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!(
"Ollama Cloud API key not found. Get a key: {}. Run 'codewhale auth set --provider ollama', set OLLAMA_API_KEY, or add [providers.ollama] api_key in ~/.codewhale/config.toml.",
help.credential_url
.unwrap_or(codewhale_config::provider::OLLAMA_CLOUD_API_KEY_URL)
)
}
// Custom OpenAI-compatible endpoints (#1519): the key comes from the
// env var named by `[providers.<name>] api_key_env`. If we reached
// here it is unset/empty (and the endpoint is not loopback).
ApiProvider::Custom => {
let provider_name = self.provider.as_deref().unwrap_or("<name>");
match self
.provider_config_for(provider)
.and_then(|entry| entry.api_key_env.as_deref())
.map(str::trim)
.filter(|name| !name.is_empty())
{
Some(env_name) => anyhow::bail!(
"Custom provider '{provider_name}' API key not found.\n\View on GitHub (pinned to 8880682c63)
Solutions
- Run codewhale auth set --provider ollama.
- Or export OLLAMA_API_KEY=<cloud key>.
- Or add api_key under [providers.ollama] in ~/.codewhale/config.toml.
- If you meant local Ollama, point base_url back at your loopback instance so the keyless self-hosted path applies.
Example fix
# before provider = "ollama" base_url = "https://remote-host:11434/v1" # non-loopback → cloud rules # after (option 1) # export OLLAMA_API_KEY=... # after (option 2, local keyless) base_url = "http://127.0.0.1:11434/v1"
Defensive patterns
Strategy: validation
Validate before calling
fn ollama_key_present(cfg: &Config) -> bool {
if provider_route_is_keyless_self_hosted(ApiProvider::Ollama, &cfg.deepseek_base_url()) {
return true; // loopback self-hosted stays keyless
}
env_nonempty("OLLAMA_API_KEY")
|| cfg.provider_config_for(ApiProvider::Ollama)
.and_then(|pc| pc.api_key)
.is_some_and(|k| !k.trim().is_empty())
|| secret_store_has(ApiProvider::Ollama)
}
anyhow::ensure!(ollama_key_present(&config), "Ollama Cloud requires a key; loopback is keyless"); Type guard
fn ollama_route_needs_key(base_url: &str) -> bool {
!base_url_uses_local_host(&base_url.to_string())
&& !provider_route_is_keyless_self_hosted(ApiProvider::Ollama, &base_url.to_string())
} Try / catch
match config.deepseek_api_key() {
Err(e) if e.to_string().starts_with("Ollama Cloud API key not found") => {
// either supply a cloud key or repoint base_url at the loopback instance
Err(e)
}
other => other,
} Prevention
- Local Ollama must be reached via a loopback base_url to stay keyless.
- For Ollama Cloud, store OLLAMA_API_KEY in the service environment or via codewhale auth set --provider ollama.
- Double-check base_url spelling — a typo silently moves you from keyless to cloud rules.
When it happens
Trigger: provider = ollama with a non-loopback base_url (or default cloud route) and no OLLAMA_API_KEY, no stored key, and no [providers.ollama] api_key.
Common situations: Pointing ollama at a remote/cloud endpoint while assuming keyless local behavior; base_url typo changing localhost to a remote host; new cloud accounts.
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 {
- xAI API key not found. Get a key: https://console.x.ai/ Run
- 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/fd3659670ba4ced1.
Report an issue: GitHub.