{"record":{"id":"57682df4338792e0","repo":"Hmbown/CodeWhale","slug":"custom-provider-provider-name-api-key-not-foun","errorCode":null,"errorMessage":"Custom provider '{provider_name}' API key not found.\nSet the environment variable {env_name} to your key, or add api_key to [providers.{provider_name}].","messagePattern":"Custom provider '(.+?)' API key not found\\.\nSet the environment variable (.+?) to your key, or add api_key to \\[providers\\.(.+?)\\]\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/config.rs","lineNumber":7449,"sourceCode":"                    credential_help_for_provider_route(provider, &self.active_route_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\\\n                         Set the environment variable {env_name} to your key, \\\n                         or add api_key to [providers.{provider_name}].\"\n                    ),\n                    None => anyhow::bail!(\n                        \"Custom provider '{provider_name}' has no auth configured.\\n\\\n                         Add api_key_env = \\\"YOUR_ENV_VAR\\\" (or api_key) to \\\n                         [providers.{provider_name}] in ~/.codewhale/config.toml.\"\n                    ),\n                }\n            }\n            _ => anyhow::bail!(\"{}\", missing_provider_api_key_message(provider)?),\n        }\n    }\n\n    /// Resolve the skills directory path.\n    #[must_use]\n    pub fn skills_dir(&self) -> PathBuf {","sourceCodeStart":7431,"sourceCodeEnd":7467,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/config.rs#L7431-L7467","documentation":"Thrown for a custom OpenAI-compatible provider when the configured api_key_env variable name exists but the key itself is missing at runtime. The config layer reads api_key_env from [providers.<name>], trims it, and if the env var it names is not set (or empty), it bails telling the developer exactly which variable to set. Custom providers must supply auth either inline or via a named env var.","triggerScenarios":"Using a custom provider that has api_key_env = \"MY_KEY\" in [providers.<name>] while MY_KEY is unset or empty in the environment.","commonSituations":"Env var defined in config but never exported; .env file not loaded in the shell/CI; key set under a different variable name than api_key_env declares; container images missing the secret.","solutions":["Export the env variable named in the error with your API key","Or add `api_key = \"...\"` directly under [providers.<name>] in ~/.codewhale/config.toml","Verify the env var name in config matches the exported name exactly (case-sensitive, no stray whitespace)"],"exampleFix":"// before\n[providers.acme]\napi_key_env = \"ACME_KEY\"  # ACME_KEY never exported\n// after (shell)\nexport ACME_KEY=\"sk-...\"\n# or in config.toml\n[providers.acme]\napi_key = \"sk-...\"","handlingStrategy":"validation","validationCode":"// custom provider declares api_key_env = \"ACME_KEY\"\nlet ok = std::env::var(\"ACME_KEY\").map(|v| !v.trim().is_empty()).unwrap_or(false);\nif !ok { eprintln!(\"ACME_KEY is not set; export it or set api_key in [providers.acme]\"); }","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"Custom provider\") && e.to_string().contains(\"API key not found\") => export_custom_key_and_retry(),\n    other => other?,\n}","preventionTips":["Export the env var named by api_key_env before launching","Load .env files in shells/CI where codewhale runs","Match env var names exactly, including case"],"tags":["authentication","api-key","env-var","custom-provider"],"backgroundTag":"missing-env-var","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}