Kuberwastaken/claurst · error
No API key found
Error message
No API key found
What it means
The API client's convenience constructor `from_config` requires an API key resolved from the app configuration or environment. When `cfg.resolve_api_key()` returns `None` — no key in config files and no relevant environment variable set — construction fails with this error. It is a fail-fast guard so requests are never sent without credentials.
Solutions
- Export the provider's API key env var (e.g. `export ANTHROPIC_API_KEY=sk-ant-...`) before launching.
- Set the API key in the app's settings/config file that `claurst_core::config::Config` reads.
- If you have the key programmatically, use `Client::new(ClientConfig { api_key, .. })` instead of `from_config`.
- In CI, add the secret to the pipeline environment rather than hardcoding it.
Example fix
// before
let client = ApiClient::from_config(&cfg)?; // panics at runtime: No API key found
// after
if cfg.resolve_api_key().is_none() {
eprintln!("Set ANTHROPIC_API_KEY before starting");
std::process::exit(1);
}
let client = ApiClient::from_config(&cfg)?; Defensive patterns
Strategy: validation
Validate before calling
// Fail fast before constructing the client
if cfg.resolve_api_key().is_none() {
anyhow::bail!("No API key: set ANTHROPIC_API_KEY or add apiKey to settings");
} Try / catch
let client = ApiClient::from_config(&cfg)
.map_err(|e| e.context("configure ANTHROPIC_API_KEY before using the API"))?; Prevention
- Export the API key env var in shell profile or CI secrets as a setup step.
- Validate config at startup (check resolve_api_key) before any feature that needs the client.
- Prefer the explicit Client::new(ClientConfig{api_key}) path in code so the requirement is visible.
- Document the required env var in README/onboarding docs.
When it happens
Trigger: Calling `Client::from_config(&config)` where the `Config` has no API key: `resolve_api_key()` finds neither a settings-file key nor a provider env var (e.g. ANTHROPIC_API_KEY).
Common situations: Fresh checkout / new machine without exporting the API key env var; settings.json missing the `apiKey` field; using a provider that needs OAuth (Claude Pro/Max) instead of an API key; typos in the env var name; CI environment without secrets injected.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- Bridge session registration failed: authentication error
- No API key found. Options: - Set ANTHROPIC_API_KEY for…
- Login succeeded but could not obtain a usable credential
- Token refresh failed
- MCP server ' ' is configured as ' ' but missing URL
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/7b8fe99a9ab06a40.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/api/src/lib.rs:674
}
/// Build a new client. Uses a `wreq`/BoringSSL client whose TLS
/// fingerprint matches Bun (the official client). An empty key is
/// allowed; validation is deferred to the first call.
pub fn new(config: ClientConfig) -> anyhow::Result<Self> {
let http = crate::bun_tls::build_anthropic_client(config.request_timeout)?;
Ok(Self {
http,
config,
session_id: uuid::Uuid::new_v4().to_string(),
})
}
/// Convenience constructor that resolves the key from config/env.
pub fn from_config(cfg: &claurst_core::config::Config) -> anyhow::Result<Self> {
let api_key = cfg
.resolve_api_key()
.ok_or_else(|| anyhow::anyhow!("No API key found"))?;
let api_base = cfg.resolve_api_base();
Self::new(ClientConfig {
api_key,
api_base,
..Default::default()
})
}
// ---- Non-streaming create message --------------------------------
/// Send a non-streaming `POST /v1/messages` and return the full response.
pub async fn create_message(
&self,
mut request: CreateMessageRequest,
) -> Result<CreateMessageResponse, ClaudeError> {
// Deferred key validation — fail here rather than at construction
// so that non-Anthropic provider setups don't crash on startup.
View on GitHub (pinned to b0637c97ec)