{"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/58e5313667b857ef39a730e380af31816a7b1768/crates/but-llm/src/anthropic.rs#L128-L164","documentation":"anthropic_own_key_creds retrieves the user's personal Anthropic API key from the secret store (handle AI_ANTHROPIC_SECRET_HANDLE, global namespace). When none is stored, it throws \"No Anthropic own key configured. Add this through the GitButler settings\". Using your own Anthropic key requires saving it in GitButler settings first.","triggerScenarios":"Selecting the OwnAnthropicKey credentials kind while secret::retrieve returns None because the key was never saved via GitButler settings or was deleted from the keyring.","commonSituations":"User switched provider to 'own key' without entering a key in settings, keyring cleared on reinstall/OS upgrade, or settings sync failed to persist the secret.","solutions":["Open GitButler settings and add your Anthropic API key","Verify the key was persisted in the OS keychain after saving","Unlock the OS keychain if secret retrieval fails silently","Or switch the provider to the GitButler-proxied one after logging in"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"let has_key = secret::retrieve(AI_ANTHROPIC_SECRET_HANDLE, secret::Namespace::Global)\n    .map(|k| k.is_some()).unwrap_or(false);\nif !has_key { eprintln!(\"add an Anthropic key in GitButler settings or use the proxied provider\"); }","typeGuard":null,"tryCatchPattern":"// fall back to the GitButler-proxied provider when no own key exists\nmatch anthropic_own_key_creds() {\n    Err(e) if e.to_string().contains(\"No Anthropic own key configured\") => gitbutler_proxied_creds(),\n    other => other,\n}","preventionTips":["Save your Anthropic API key in GitButler settings before switching providers","Check the OS keychain still holds the key after OS upgrades or reinstalls","Surface a settings prompt in UI flows when this credential kind is selected"],"tags":["llm","api-key","secrets","configuration"],"backgroundTag":"missing-api-key","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}