gitbutlerapp/gitbutler · error

No Anthropic own key configured. Add this through the GitBut

Error message

No Anthropic own key configured. Add this through the GitButler settings

What it means

Thrown by AnthropicProvider::anthropic_own_key_creds in crates/but-llm/src/anthropic.rs when secret::retrieve(AI_ANTHROPIC_SECRET_HANDLE, Namespace::Global) returns None — no user-supplied Anthropic API key has been saved. This path runs when OwnAnthropicKey credentials are requested explicitly or when the fallback chain reaches it after the GitButler token is absent.

Source

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

        let credentials = &self.credentials.1;
        let kind = self.credentials.0.clone();
        AnthropicClient::new(kind, credentials)
    }

    pub fn credentials_kind(&self) -> CredentialsKind {
        self.credentials.0.clone()
    }
    fn gitbutler_proxied_creds() -> Result<(CredentialsKind, Sensitive<String>)> {
        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))
    }
}

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Add an Anthropic API key in GitButler settings (it is stored under the AI_ANTHROPIC_SECRET_HANDLE secret).
  2. Or log in to GitButler to use the proxied provider instead.
  3. Or export ANTHROPIC_API_KEY and let the env-var credential path supply the key.
Defensive patterns

Strategy: fallback

Validate before calling

let has_own_key = secret::retrieve(AI_ANTHROPIC_SECRET_HANDLE, secret::Namespace::Global).ok().flatten().is_some();
if !has_own_key { /* pick proxied or env-var credentials instead */ }

Type guard

fn has_own_anthropic_key() -> bool {
    secret::retrieve(AI_ANTHROPIC_SECRET_HANDLE, secret::Namespace::Global)
        .ok()
        .flatten()
        .is_some()
}

Try / catch

let provider = AnthropicProvider::with(Some(CredentialsKind::OwnAnthropicKey), model)
    .or_else(|| AnthropicProvider::with(None, model));

Prevention

When it happens

Trigger: AnthropicProvider::with(Some(CredentialsKind::OwnAnthropicKey), _) with no key saved in settings; fallback chain reaching this function when the user is neither logged in nor has ANTHROPIC_API_KEY set.

Common situations: Fresh installs where neither login nor a key was configured; the settings secret was removed or the OS keychain entry deleted; automated environments that never opened the settings UI.

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