Hmbown/CodeWhale · error
Custom provider ' ' has no auth configured. Add api_key_env…
Error message
Custom provider '{provider_name}' has no auth configured.
Add api_key_env = "YOUR_ENV_VAR" (or api_key) to [providers.{provider_name}] in ~/.codewhale/config.toml. What it means
Thrown for a custom provider that has no auth configuration at all: no usable api_key_env name and no inline api_key. It is the `None` arm of the custom-provider key lookup and instructs the user to declare one of the two supported auth fields in the provider's config table. Without it, requests would go out with no credential.
Solutions
- Add `api_key_env = "YOUR_ENV_VAR"` to [providers.<name>] in ~/.codewhale/config.toml and export that variable
- Or add `api_key = "..."` directly to the [providers.<name>] table
- Check for typos: the fields are exactly `api_key` and `api_key_env`
Example fix
// before [providers.acme] base_url = "https://api.acme.dev/v1" // after [providers.acme] base_url = "https://api.acme.dev/v1" api_key_env = "ACME_API_KEY"
Defensive patterns
Strategy: validation
Validate before calling
// check the custom provider table declares auth before use
// config.toml must contain, under [providers.<name>]: api_key or api_key_env
let cfg = std::fs::read_to_string("~/.codewhale/config.toml")?;
let has_auth = cfg.contains("api_key") || cfg.contains("api_key_env");
if !has_auth { eprintln!("custom provider has no auth configured"); } Try / catch
match result {
Err(e) if e.to_string().contains("has no auth configured") => add_api_key_field_to_provider_table(),
other => other?,
} Prevention
- Always pair a custom base_url with api_key or api_key_env
- Copy a working provider table as a template
- Validate config after hand edits
When it happens
Trigger: A [providers.<name>] entry (or the provider being referenced) defines a base URL but neither api_key nor api_key_env, and the provider is used for a request.
Common situations: Hand-written custom provider table missing the auth fields; copied config from a provider that used a different auth mechanism; typo'd key names (e.g. apikey, api-key).
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- advisor model ` ` resolved only to a custom provider kind…
- custom provider base URL is invalid
- custom provider ' ' must set [providers. ].kind =…
- Custom provider ' ' API key not found. Set the environment…
- custom providers store base_url in their named
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/806cd99ed92454a9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/config.rs:7454
)
}
// 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\
Set the environment variable {env_name} to your key, \
or add api_key to [providers.{provider_name}]."
),
None => anyhow::bail!(
"Custom provider '{provider_name}' has no auth configured.\n\
Add api_key_env = \"YOUR_ENV_VAR\" (or api_key) to \
[providers.{provider_name}] in ~/.codewhale/config.toml."
),
}
}
_ => anyhow::bail!("{}", missing_provider_api_key_message(provider)?),
}
}
/// Resolve the skills directory path.
#[must_use]
pub fn skills_dir(&self) -> PathBuf {
self.skills_dir
.as_deref()
.map(expand_path)
.or_else(default_skills_dir)
.unwrap_or_else(|| PathBuf::from("./skills"))View on GitHub (pinned to 73e0f67d83)