{"record":{"id":"fcb5fbe89aba7985","repo":"gitbutlerapp/gitbutler","slug":"no-anthropic-own-key-configured-add-this-through","errorCode":null,"errorMessage":"No Anthropic own key configured. Add this through the GitButler settings","messagePattern":"No Anthropic own key configured\\. Add this through the GitButler settings","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-llm/src/anthropic.rs","lineNumber":146,"sourceCode":"        let credentials = &self.credentials.1;\n        let kind = self.credentials.0.clone();\n        AnthropicClient::new(kind, credentials)\n    }\n\n    pub fn credentials_kind(&self) -> CredentialsKind {\n        self.credentials.0.clone()\n    }\n    fn gitbutler_proxied_creds() -> Result<(CredentialsKind, Sensitive<String>)> {\n        let creds = secret::retrieve(GITBUTLER_ACCESS_TOKEN_HANDLE, secret::Namespace::BuildKind)?\n            .ok_or(anyhow::anyhow!(\n                \"No GitButler token available. Log-in to use the GitButler Anthropic provider\"\n            ))?;\n        Ok((CredentialsKind::GitButlerProxied, creds))\n    }\n\n    fn anthropic_own_key_creds() -> Result<(CredentialsKind, Sensitive<String>)> {\n        let creds = secret::retrieve(AI_ANTHROPIC_SECRET_HANDLE, secret::Namespace::Global)?\n            .ok_or(anyhow::anyhow!(\n                \"No Anthropic own key configured. Add this through the GitButler settings\"\n            ))?;\n        Ok((CredentialsKind::OwnAnthropicKey, creds))\n    }\n\n    fn anthropic_env_var_creds() -> Result<(CredentialsKind, Sensitive<String>)> {\n        let creds = Sensitive(\n            std::env::var_os(\"ANTHROPIC_API_KEY\")\n                .ok_or(anyhow::anyhow!(\n                    \"Environment variable ANTHROPIC_API_KEY is not set\"\n                ))?\n                .into_string()\n                .map_err(|_| anyhow::anyhow!(\"Invalid UTF-8 in ANTHROPIC_API_KEY\"))?,\n        );\n        Ok((CredentialsKind::EnvVarAnthropicKey, creds))\n    }\n}\n","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-llm/src/anthropic.rs#L128-L164","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add an Anthropic API key in GitButler settings (it is stored under the AI_ANTHROPIC_SECRET_HANDLE secret).","Or log in to GitButler to use the proxied provider instead.","Or export ANTHROPIC_API_KEY and let the env-var credential path supply the key."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"let has_own_key = secret::retrieve(AI_ANTHROPIC_SECRET_HANDLE, secret::Namespace::Global).ok().flatten().is_some();\nif !has_own_key { /* pick proxied or env-var credentials instead */ }","typeGuard":"fn has_own_anthropic_key() -> bool {\n    secret::retrieve(AI_ANTHROPIC_SECRET_HANDLE, secret::Namespace::Global)\n        .ok()\n        .flatten()\n        .is_some()\n}","tryCatchPattern":"let provider = AnthropicProvider::with(Some(CredentialsKind::OwnAnthropicKey), model)\n    .or_else(|| AnthropicProvider::with(None, model));","preventionTips":["Save the API key via GitButler settings instead of relying on ad-hoc storage.","In library code, request credentials with preferred_creds = None to use the built-in fallback chain.","Document that OwnAnthropicKey requires the settings entry, not just any local file."],"tags":["llm","anthropic","api-key","credentials","settings"],"backgroundTag":"missing-api-key","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-23T11:17:13.642Z"}