Kuberwastaken/claurst · error
No API key found. Options: - Set ANTHROPIC_API_KEY for…
Error message
No API key found. Options: - Set ANTHROPIC_API_KEY for Anthropic - Set OPENAI_API_KEY for OpenAI - Set GOOGLE_API_KEY for Google Gemini - Set GROQ_API_KEY for Groq (fast, free tier available) - Run `claurst --provider ollama` for local models (no key needed) - Run `claurst auth login` for Anthropic OAuth
What it means
At startup, when the active provider is Anthropic, main resolves credentials via resolve_anthropic_auth_async (API key from config/env, or saved OAuth tokens). In headless (`--print`) mode there is no interactive prompt/OAuth flow available, so if no credentials resolve at all the program bails with a message listing every supported way to supply a key.
Solutions
- Export a key: `export ANTHROPIC_API_KEY=sk-ant-...` (or set OPENAI_API_KEY / GOOGLE_API_KEY / GROQ_API_KEY and select that provider)
- Run `claurst auth login` interactively once to store Anthropic OAuth tokens; headless runs will then resolve them
- For CI/headless without any key, use the local provider: `claurst --provider ollama --print "..."` (no key required)
- Run `claurst --provider <other> --print "..."` if you have a key for a non-Anthropic provider but none for Anthropic
- Check that the env var actually reaches the process (`env | grep API_KEY` inside the same context CI/cron uses) and that ~/.claurst auth store is populated on this machine/user
Example fix
// before: headless run with no credentials in scope
ci-job: claurst --print "summarize" // -> No API key found
// after: provide credentials to the headless environment
ci-job:
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
script: claurst --print "summarize" Defensive patterns
Strategy: validation
Validate before calling
# Verify a credential source exists before a headless run
[ -n "$ANTHROPIC_API_KEY" ] || [ -f "$HOME/.claurst/auth.json" ] \
|| { echo "No Anthropic credentials for headless run"; exit 1; } Try / catch
# Fall back to a keyless local provider when no key is present if ! claurst --print "task" 2>/dev/null; then claurst --provider ollama --print "task" fi
Prevention
- Set ANTHROPIC_API_KEY in the environment that actually runs the process (CI env secrets, cron, systemd), not only the interactive shell
- Run `claurst auth login` once per machine/user so OAuth tokens backstop missing keys
- Use --provider ollama for keyless headless/local work
- Smoke-test headless mode (`claurst --print "hi"`) in CI before real jobs
When it happens
Trigger: Running claurst in headless mode (`--print`, or a non-TTY environment) with the active provider resolving to "anthropic" while: ANTHROPIC_API_KEY is unset, no key is stored in settings/config, and no Anthropic OAuth tokens exist in the auth store. resolve_anthropic_auth_async returns None and is_headless is true.
Common situations: Fresh machine or CI container without exported credentials; ANTHROPIC_API_KEY defined only in an interactive shell profile but not in the cron/CI environment; switching back to the default Anthropic provider after previously using another provider; running via a wrapper (editor plugin, script) that drops environment variables.
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
- Login succeeded but could not obtain a usable credential
- No API key found for voice transcription. Set…
- Invalid : contains unsafe characters
- API key creation failed
- Token refresh failed
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/8f7d450d0dc98270.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/cli/src/main.rs:617
}
if let Some(ref append) = config.append_system_prompt {
system_parts.push(append.clone());
}
let system_prompt = system_parts.join("\n\n");
// Initialize API client.
// Try config/env first; fall back to saved OAuth tokens.
// If no Anthropic credentials are found, check whether any other provider is
// configured (OpenAI, Google, Ollama, Groq, etc.) — if so, proceed without
// requiring Anthropic auth. Only launch the OAuth flow when Anthropic is
// explicitly the intended provider and no key exists at all.
let active_provider = config.selected_provider_id();
let (api_key, use_bearer_auth) = if active_provider == "anthropic" {
match config.resolve_anthropic_auth_async().await {
Some(auth) => auth,
None => {
if is_headless {
anyhow::bail!(
"No API key found. Options:\n\
- Set ANTHROPIC_API_KEY for Anthropic\n\
- Set OPENAI_API_KEY for OpenAI\n\
- Set GOOGLE_API_KEY for Google Gemini\n\
- Set GROQ_API_KEY for Groq (fast, free tier available)\n\
- Run `claurst --provider ollama` for local models (no key needed)\n\
- Run `claurst auth login` for Anthropic OAuth"
);
} else {
(String::new(), false)
}
}
}
} else {
(String::new(), false)
};
// Apply the user-configured request timeout (issue #175) before building anyView on GitHub (pinned to b0637c97ec)