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

  1. Export a key: `export ANTHROPIC_API_KEY=sk-ant-...` (or set OPENAI_API_KEY / GOOGLE_API_KEY / GROQ_API_KEY and select that provider)
  2. Run `claurst auth login` interactively once to store Anthropic OAuth tokens; headless runs will then resolve them
  3. For CI/headless without any key, use the local provider: `claurst --provider ollama --print "..."` (no key required)
  4. Run `claurst --provider <other> --print "..."` if you have a key for a non-Anthropic provider but none for Anthropic
  5. 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

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


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 any

View on GitHub (pinned to b0637c97ec)