Hmbown/CodeWhale · error · anyhow::Error
DeepSeek API key not found. 1. Get a key: https://platform
Error message
DeepSeek API key not found. 1. Get a key: https://platform.deepseek.com/api_keys 2. Save it (works in every folder, no OS prompts): codewhale auth set --provider deepseek Alternatives: • export DEEPSEEK_API_KEY=<your-key> (current shell only; also note: zsh users — exports in ~/.zshrc only reach interactive shells, prefer ~/.zshenv for everything) • api_key = "<your-key>" in ~/.codewhale/config.toml • already configured DeepSeek Harness? grant read-only access: codewhale auth external-consent --provider deepseek --mode read-only
What it means
Raised when provider is DeepSeek/DeepSeekCN, no custom endpoint is in play, and no credential was found in any source: the durable auth store, DEEPSEEK_API_KEY, config api_key, or an external DeepSeek Harness consent. The message walks through each remedy in order and notes the zsh quirk that ~/.zshrc exports only reach interactive shells.
Source
Thrown at crates/tui/src/config.rs:6353
&& (provider_route_is_keyless_self_hosted(provider, &self.deepseek_base_url())
|| base_url_uses_local_host(&self.deepseek_base_url()))
{
return Ok(String::new());
}
if custom_endpoint {
let route_name = self
.provider
.as_deref()
.unwrap_or_else(|| provider.as_str());
anyhow::bail!(
"Custom endpoint credentials for {route_name} must be bound explicitly. Ambient provider credentials are not sent to {}. Add api_key or api_key_env to this provider route, or pass --api-key with --base-url.",
self.deepseek_base_url()
);
}
match provider {
ApiProvider::Deepseek | ApiProvider::DeepseekCN => anyhow::bail!(
"DeepSeek API key not found.\n\
\n\
1. Get a key: https://platform.deepseek.com/api_keys\n\
2. Save it (works in every folder, no OS prompts):\n\
codewhale auth set --provider deepseek\n\
\n\
Alternatives:\n\
• export DEEPSEEK_API_KEY=<your-key> (current shell only;\n\
also note: zsh users — exports in ~/.zshrc only reach interactive\n\
shells, prefer ~/.zshenv for everything)\n\
• api_key = \"<your-key>\" in ~/.codewhale/config.toml\n\
• already configured DeepSeek Harness? grant read-only access:\n\
codewhale auth external-consent --provider deepseek --mode read-only"
),
ApiProvider::SiliconflowCn => anyhow::bail!(
"SiliconFlow China API key not found. Get a key: {}. Run 'codewhale auth set --provider siliconflow-CN', \
set {}, or add [{}] api_key in ~/.codewhale/config.toml. \
[providers.siliconflow] remains a fallback when the CN table omits api_key.",View on GitHub (pinned to 8880682c63)
Solutions
- Run codewhale auth set --provider deepseek (works in every folder, no OS prompts).
- Or export DEEPSEEK_API_KEY=<key> — on zsh prefer ~/.zshenv so non-interactive shells inherit it.
- Or set api_key = "<key>" in ~/.codewhale/config.toml.
- If DeepSeek Harness is already configured, grant read-only access: codewhale auth external-consent --provider deepseek --mode read-only.
Example fix
# before: no credentials anywhere provider = "deepseek" # after (terminal) # codewhale auth set --provider deepseek # or: export DEEPSEEK_API_KEY=sk-... (put in ~/.zshenv for zsh)
Defensive patterns
Strategy: validation
Validate before calling
fn deepseek_key_present(cfg: &Config) -> bool {
std::env::var("DEEPSEEK_API_KEY").map(|v| !v.trim().is_empty()).unwrap_or(false)
|| cfg.provider_config_for(ApiProvider::Deepseek)
.and_then(|pc| pc.api_key.clone())
.is_some_and(|k| !k.trim().is_empty())
|| secret_store_has(ApiProvider::Deepseek) // codewhale auth set
}
anyhow::ensure!(deepseek_key_present(&config), "configure DeepSeek auth first"); Type guard
fn deepseek_credentials_configured(cfg: &Config) -> bool {
deepseek_key_present(cfg)
} Try / catch
match config.deepseek_api_key() {
Err(e) if e.to_string().starts_with("DeepSeek API key not found") => {
// interactive setup path: run `codewhale auth set --provider deepseek`, then retry once
run_auth_set(ApiProvider::Deepseek)?;
config.deepseek_api_key()
}
other => other,
} Prevention
- Run codewhale auth set --provider deepseek once per machine instead of ad-hoc exports.
- Put DEEPSEEK_API_KEY in ~/.zshenv (zsh) or the service environment, not just interactive rc files.
- Re-check credentials after `auth logout` wipes the secret store.
When it happens
Trigger: Fresh install with provider = deepseek and no auth ever configured; DEEPSEEK_API_KEY exported only in an interactive shell but codewhale launched from a service; key deleted from the secret store via logout.
Common situations: New machines/containers; CI runners without secrets wired; after `auth logout` wiped stored keys (#343); zsh users whose exports live in ~/.zshrc.
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
- Ollama Cloud API key not found. Get a key: {}. Run 'codewhal
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/1d4f2094651184ad.
Report an issue: GitHub.