{"record":{"id":"3776862c21550077","repo":"gitbutlerapp/gitbutler","slug":"environment-variable-anthropic-api-key-is-not-set","errorCode":null,"errorMessage":"Environment variable ANTHROPIC_API_KEY is not set","messagePattern":"Environment variable ANTHROPIC_API_KEY is not set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-llm/src/anthropic.rs","lineNumber":155,"sourceCode":"        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\nimpl LLMClient for AnthropicProvider {\n    fn model(&self) -> Option<String> {\n        self.model.clone()\n    }\n\n    fn tool_calling_loop_stream(\n        &self,\n        system_message: &str,\n        chat_messages: Vec<ChatMessage>,","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-llm/src/anthropic.rs#L137-L173","documentation":"This error is thrown by `anthropic_env_var_creds` in the Anthropic LLM provider when no `ANTHROPIC_API_KEY` environment variable is present in the process environment. The function falls back to reading the key from the environment when no stored (own-key) credentials are available, so a missing variable means no usable API credential at all. It is an anyhow error raised before any network request is made.","triggerScenarios":"Calling the Anthropic provider's credential resolution path (`anthropic_env_var_creds`) when `std::env::var_os(\"ANTHROPIC_API_KEY\")` returns None — i.e. the variable is unset or set to an empty-but-absent value is not possible (empty string still counts as set), so strictly: the variable is not defined in the environment.","commonSituations":"Running `but` CLI or the desktop app's Rust backend without exporting ANTHROPIC_API_KEY; CI environments where secrets are not injected; having the key set only in a shell profile not loaded by the GUI-launched process; typos in the variable name.","solutions":["Set the environment variable before running: export ANTHROPIC_API_KEY=sk-ant-...","If launched from a GUI (desktop app), set the key via launchctl setenv / system environment settings so the child process inherits it","Configure a stored Anthropic key through GitButler settings so the env-var fallback is not needed","In CI, add ANTHROPIC_API_KEY as a secret environment input to the job"],"exampleFix":"// before\n$ but ai ...\nError: Environment variable ANTHROPIC_API_KEY is not set\n\n// after\n$ export ANTHROPIC_API_KEY=sk-ant-api03-...\n$ but ai ...","handlingStrategy":"validation","validationCode":"fn have_anthropic_key() -> bool {\n    std::env::var_os(\"ANTHROPIC_API_KEY\")\n        .map(|v| !v.is_empty())\n        .unwrap_or(false)\n}\nif !have_anthropic_key() { eprintln!(\"Set ANTHROPIC_API_KEY before calling the AI provider\"); }","typeGuard":null,"tryCatchPattern":"match provider.new() {\n    Err(e) if e.to_string().contains(\"ANTHROPIC_API_KEY\") => {\n        eprintln!(\"Set ANTHROPIC_API_KEY in your environment\");\n    }\n    Err(e) => return Err(e),\n    Ok(p) => p,\n}","preventionTips":["Add ANTHROPIC_API_KEY to your shell profile or direnv .envrc","For GUI apps, set the key at the session/system level, not just interactive shells","Inject the secret explicitly in CI/CD job configuration","Prefer storing keys in GitButler settings over env-var fallback"],"tags":["environment","api-key","llm","configuration"],"backgroundTag":"missing-env-var","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"}