gitbutlerapp/gitbutler · error

Environment variable ANTHROPIC_API_KEY is not set

Error message

Environment variable ANTHROPIC_API_KEY is not set

What it means

Thrown by AnthropicProvider::anthropic_env_var_creds in crates/but-llm/src/anthropic.rs when std::env::var_os("ANTHROPIC_API_KEY") returns None. This is the last rung of the credential fallback chain (proxied token -> own key -> env var), so hitting it means no Anthropic credential source is available at all.

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 caf1f223d3)

Solutions

  1. Export ANTHROPIC_API_KEY in the shell or service environment that runs the binary.
  2. Or log in to GitButler / save an own key so earlier fallback rungs succeed.
  3. For daemons/CI, inject the variable via the service's environment configuration rather than the interactive shell.

Example fix

# before
$ but ai ...
# error: Environment variable ANTHROPIC_API_KEY is not set

# after
$ export ANTHROPIC_API_KEY="sk-ant-..."
$ but ai ...
Defensive patterns

Strategy: validation

Validate before calling

// Rust: check before selecting the env-var provider
let key_present = std::env::var_os("ANTHROPIC_API_KEY").is_some();

// Shell (CI): guard the whole step
// [ -n "$ANTHROPIC_API_KEY" ] || { echo "ANTHROPIC_API_KEY missing"; exit 1; }

Type guard

fn anthropic_env_key_available() -> bool {
    std::env::var_os("ANTHROPIC_API_KEY")
        .map(|v| v.to_str().map(|s| !s.is_empty()).unwrap_or(false))
        .unwrap_or(false)
}

Try / catch

let provider = match AnthropicProvider::with(Some(CredentialsKind::EnvVarAnthropicKey), model) {
    Some(p) => p,
    None => AnthropicProvider::with(None, model).expect("no Anthropic credentials"),
};

Prevention

When it happens

Trigger: AnthropicProvider::with(Some(CredentialsKind::EnvVarAnthropicKey), _) without the variable exported; the full fallback chain reached with no login, no saved key, and no env var; the variable set only in the desktop app's environment but not in the shell running the CLI.

Common situations: Running but/CLI in a fresh shell, container, or CI where ANTHROPIC_API_KEY was never exported; setting the var in .zshrc but launching from an environment that does not source it; systemd/launchd services with a restricted environment.

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@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/3776862c21550077. Report an issue: GitHub.