{"record":{"id":"fd3659670ba4ced1","repo":"Hmbown/CodeWhale","slug":"ollama-cloud-api-key-not-found-get-a-key-run","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/config.rs","lineNumber":6438,"sourceCode":"                anyhow::bail!(\n                    \"xAI API key not found. Get a key: https://console.x.ai/\\n\\\n                     Run 'codewhale auth set --provider xai', set XAI_API_KEY, or add \\\n                     [providers.xai] api_key.\\n\\\n                     OAuth alternative: run `codewhale auth xai-device` for \\\n                     Codewhale-owned storage and set [providers.xai] auth_mode = \\\"oauth\\\".\"\n                );\n            }\n            // Self-hosted deployments commonly run without auth on localhost.\n            // Return an empty key and let the client omit the Authorization header.\n            ApiProvider::Sglang | ApiProvider::Vllm => Ok(String::new()),\n            ApiProvider::Ollama\n                if provider_route_is_keyless_self_hosted(provider, &self.deepseek_base_url()) =>\n            {\n                Ok(String::new())\n            }\n            ApiProvider::Ollama => {\n                let help = credential_help_for_provider_route(provider, &self.deepseek_base_url());\n                anyhow::bail!(\n                    \"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.\",\n                    help.credential_url\n                        .unwrap_or(codewhale_config::provider::OLLAMA_CLOUD_API_KEY_URL)\n                )\n            }\n            // Custom OpenAI-compatible endpoints (#1519): the key comes from the\n            // env var named by `[providers.<name>] api_key_env`. If we reached\n            // here it is unset/empty (and the endpoint is not loopback).\n            ApiProvider::Custom => {\n                let provider_name = self.provider.as_deref().unwrap_or(\"<name>\");\n                match self\n                    .provider_config_for(provider)\n                    .and_then(|entry| entry.api_key_env.as_deref())\n                    .map(str::trim)\n                    .filter(|name| !name.is_empty())\n                {\n                    Some(env_name) => anyhow::bail!(\n                        \"Custom provider '{provider_name}' API key not found.\\n\\","sourceCodeStart":6420,"sourceCodeEnd":6456,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/config.rs#L6420-L6456","documentation":"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).","triggerScenarios":"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.","commonSituations":"Pointing ollama at a remote/cloud endpoint while assuming keyless local behavior; base_url typo changing localhost to a remote host; new cloud accounts.","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."],"exampleFix":"# before\nprovider = \"ollama\"\nbase_url = \"https://remote-host:11434/v1\"   # non-loopback → cloud rules\n\n# after (option 1)\n# export OLLAMA_API_KEY=...\n# after (option 2, local keyless)\nbase_url = \"http://127.0.0.1:11434/v1\"","handlingStrategy":"validation","validationCode":"fn ollama_key_present(cfg: &Config) -> bool {\n    if provider_route_is_keyless_self_hosted(ApiProvider::Ollama, &cfg.deepseek_base_url()) {\n        return true; // loopback self-hosted stays keyless\n    }\n    env_nonempty(\"OLLAMA_API_KEY\")\n        || cfg.provider_config_for(ApiProvider::Ollama)\n            .and_then(|pc| pc.api_key)\n            .is_some_and(|k| !k.trim().is_empty())\n        || secret_store_has(ApiProvider::Ollama)\n}\n\nanyhow::ensure!(ollama_key_present(&config), \"Ollama Cloud requires a key; loopback is keyless\");","typeGuard":"fn ollama_route_needs_key(base_url: &str) -> bool {\n    !base_url_uses_local_host(&base_url.to_string())\n        && !provider_route_is_keyless_self_hosted(ApiProvider::Ollama, &base_url.to_string())\n}","tryCatchPattern":"match config.deepseek_api_key() {\n    Err(e) if e.to_string().starts_with(\"Ollama Cloud API key not found\") => {\n        // either supply a cloud key or repoint base_url at the loopback instance\n        Err(e)\n    }\n    other => other,\n}","preventionTips":["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."],"tags":["rust","ollama","api-key","self-hosted","authentication","config"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}