gitbutlerapp/gitbutler · error

Environment variable ANTHROPIC_API_KEY is not set

Error message

Environment variable ANTHROPIC_API_KEY is not set

What it means

This error is thrown by `anthropic_env_var_creds` in the Anthropic LLM provider when no `ANTHROPIC_API_KEY` environment variable is present in the process environment. The function falls back to reading the key from the environment when no stored (own-key) credentials are available, so a missing variable means no usable API credential at all. It is an anyhow error raised before any network request is made.

Solutions

  1. Set the environment variable before running: export ANTHROPIC_API_KEY=sk-ant-...
  2. If launched from a GUI (desktop app), set the key via launchctl setenv / system environment settings so the child process inherits it
  3. Configure a stored Anthropic key through GitButler settings so the env-var fallback is not needed
  4. In CI, add ANTHROPIC_API_KEY as a secret environment input to the job

Example fix

// before
$ but ai ...
Error: Environment variable ANTHROPIC_API_KEY is not set

// after
$ export ANTHROPIC_API_KEY=sk-ant-api03-...
$ but ai ...
Defensive patterns

Strategy: validation

Validate before calling

fn have_anthropic_key() -> bool {
    std::env::var_os("ANTHROPIC_API_KEY")
        .map(|v| !v.is_empty())
        .unwrap_or(false)
}
if !have_anthropic_key() { eprintln!("Set ANTHROPIC_API_KEY before calling the AI provider"); }

Try / catch

match provider.new() {
    Err(e) if e.to_string().contains("ANTHROPIC_API_KEY") => {
        eprintln!("Set ANTHROPIC_API_KEY in your environment");
    }
    Err(e) => return Err(e),
    Ok(p) => p,
}

Prevention

When it happens

Trigger: Calling the Anthropic provider's credential resolution path (`anthropic_env_var_creds`) when `std::env::var_os("ANTHROPIC_API_KEY")` returns None — i.e. the variable is unset or set to an empty-but-absent value is not possible (empty string still counts as set), so strictly: the variable is not defined in the environment.

Common situations: Running `but` CLI or the desktop app's Rust backend without exporting ANTHROPIC_API_KEY; CI environments where secrets are not injected; having the key set only in a shell profile not loaded by the GUI-launched process; typos in the variable name.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/3776862c21550077. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-llm/src/anthropic.rs:155

        let creds = secret::retrieve(GITBUTLER_ACCESS_TOKEN_HANDLE, secret::Namespace::BuildKind)?
            .ok_or(anyhow::anyhow!(
                "No GitButler token available. Log-in to use the GitButler Anthropic provider"
            ))?;
        Ok((CredentialsKind::GitButlerProxied, creds))
    }

    fn anthropic_own_key_creds() -> Result<(CredentialsKind, Sensitive<String>)> {
        let creds = secret::retrieve(AI_ANTHROPIC_SECRET_HANDLE, secret::Namespace::Global)?
            .ok_or(anyhow::anyhow!(
                "No Anthropic own key configured. Add this through the GitButler settings"
            ))?;
        Ok((CredentialsKind::OwnAnthropicKey, creds))
    }

    fn anthropic_env_var_creds() -> Result<(CredentialsKind, Sensitive<String>)> {
        let creds = Sensitive(
            std::env::var_os("ANTHROPIC_API_KEY")
                .ok_or(anyhow::anyhow!(
                    "Environment variable ANTHROPIC_API_KEY is not set"
                ))?
                .into_string()
                .map_err(|_| anyhow::anyhow!("Invalid UTF-8 in ANTHROPIC_API_KEY"))?,
        );
        Ok((CredentialsKind::EnvVarAnthropicKey, creds))
    }
}

impl LLMClient for AnthropicProvider {
    fn model(&self) -> Option<String> {
        self.model.clone()
    }

    fn tool_calling_loop_stream(
        &self,
        system_message: &str,
        chat_messages: Vec<ChatMessage>,

View on GitHub (pinned to 58e5313667)