{"record":{"id":"946d05c53e607687","repo":"gitbutlerapp/gitbutler","slug":"no-gitbutler-token-available-log-in-to-use-the-gi","errorCode":null,"errorMessage":"No GitButler token available. Log-in to use the GitButler Anthropic provider","messagePattern":"No GitButler token available\\. Log-in to use the GitButler Anthropic provider","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-llm/src/anthropic.rs","lineNumber":138,"sourceCode":"            Err(e) => {\n                tracing::error!(\"Failed to retrieve Anthropic credentials: {}\", e);\n                None\n            }\n        }\n    }\n\n    pub fn client(&self) -> Result<AnthropicClient> {\n        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\"","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-llm/src/anthropic.rs#L120-L156","documentation":"gitbutler_proxied_creds retrieves the GitButler access token from the OS secret store (handle GITBUTLER_ACCESS_TOKEN_HANDLE) to use the Anthropic provider proxied through GitButler. When no token is stored, it throws \"No GitButler token available. Log-in to use the GitButler Anthropic provider\". It is an authentication precondition, not a network failure.","triggerScenarios":"Selecting the GitButler-proxied Anthropic provider while secret::retrieve returns None because the user has never logged in to GitButler or the token was removed from the keyring.","commonSituations":"Fresh machine/install without login, keychain/keyring access denied or cleared, CI containers with no stored credentials, or logging out then invoking LLM features.","solutions":["Log in to GitButler (but login / the desktop app sign-in) so an access token is stored","Check the OS keychain/keyring is accessible (unlock gnome-keyring/login keychain)","Verify the token handle exists in the secret store after login","Alternatively configure your own Anthropic API key and switch providers"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check for a stored token before selecting the provider\nlet has_token = secret::retrieve(GITBUTLER_ACCESS_TOKEN_HANDLE, secret::Namespace::BuildKind)\n    .map(|t| t.is_some()).unwrap_or(false);\nif !has_token { eprintln!(\"log in to GitButler first\"); }","typeGuard":null,"tryCatchPattern":"// fall back to another provider or prompt for login\nmatch select_anthropic_provider().await {\n    Err(e) if e.to_string().contains(\"No GitButler token available\") => {\n        prompt_gitbutler_login()?;\n    }\n    other => other?,\n}","preventionTips":["Run `but login` (or app sign-in) before using LLM features","In CI, provision a token in the keyring or use an env-var-based provider","After logout, re-authenticate before invoking proxied providers"],"tags":["llm","authentication","secrets"],"backgroundTag":"authentication-required","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"}