{"record":{"id":"a71dec370e43fe00","repo":"gitbutlerapp/gitbutler","slug":"environment-variable-openai-api-key-is-not-set","errorCode":null,"errorMessage":"Environment variable OPENAI_API_KEY is not set","messagePattern":"Environment variable OPENAI_API_KEY is not set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-llm/src/openai.rs","lineNumber":102,"sourceCode":"            .ok_or(anyhow::anyhow!(\n                \"No GitButler token available. Log-in to use the GitButler OpenAI provider\"\n            ))?;\n        Ok((CredentialsKind::GitButlerProxied, creds))\n    }\n\n    fn openai_own_key_creds() -> Result<(CredentialsKind, Sensitive<String>)> {\n        let creds = secret::retrieve(AI_OPENAI_SECRET_HANDLE, secret::Namespace::Global)?.ok_or(\n            anyhow::anyhow!(\n                \"No OpenAI own key configured. Add this through the GitButler settings\"\n            ),\n        )?;\n        Ok((CredentialsKind::OwnOpenAiKey, creds))\n    }\n\n    fn openai_env_var_creds() -> Result<(CredentialsKind, Sensitive<String>)> {\n        let creds = Sensitive(\n            std::env::var_os(\"OPENAI_API_KEY\")\n                .ok_or(anyhow::anyhow!(\n                    \"Environment variable OPENAI_API_KEY is not set\"\n                ))?\n                .into_string()\n                .map_err(|_| anyhow::anyhow!(\"Invalid UTF-8 in OPENAI_API_KEY\"))?,\n        );\n        Ok((CredentialsKind::EnvVarOpenAiKey, creds))\n    }\n}\n\nimpl OpenAIClientProvider for OpenAiProvider {\n    fn client(&self) -> Result<Client<OpenAIConfig>> {\n        match &self.credentials {\n            (CredentialsKind::EnvVarOpenAiKey, _) => {\n                let config = self.configure_custom_endpoint(OpenAIConfig::new());\n                Ok(Client::with_config(config))\n            }\n            (CredentialsKind::OwnOpenAiKey, key) => {\n                let config =","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-llm/src/openai.rs#L84-L120","documentation":"Thrown by `openai_env_var_creds` when the `OPENAI_API_KEY` environment variable is not present. This is the last fallback credential source for the OpenAI provider; if the variable is unset, there is no credential and the provider raises this anyhow error before any network call.","triggerScenarios":"`std::env::var_os(\"OPENAI_API_KEY\")` returns None during credential resolution — the variable is undefined in the environment of the process invoking the provider.","commonSituations":"Running in a shell/CI without the export; key set for the user but not for a GUI-launched process; variable named differently (e.g. OPENAI_KEY); Docker container launched without -e OPENAI_API_KEY.","solutions":["Set the variable: export OPENAI_API_KEY=sk-...","For GUI-launched apps, set the key at the system/session level so child processes inherit it","In Docker/CI, pass the variable explicitly (docker run -e / CI secret)","Or store the key in GitButler settings / log in for the proxied provider instead"],"exampleFix":"// before\n$ cargo run -- ai ...\nError: Environment variable OPENAI_API_KEY is not set\n\n// after\n$ export OPENAI_API_KEY=sk-proj-...\n$ cargo run -- ai ...","handlingStrategy":"validation","validationCode":"fn have_openai_key() -> bool {\n    std::env::var_os(\"OPENAI_API_KEY\")\n        .map(|v| !v.is_empty())\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"OPENAI_API_KEY\") => {\n        eprintln!(\"export OPENAI_API_KEY=sk-... and retry\");\n    }\n    r => r?,\n}","preventionTips":["Export OPENAI_API_KEY in your shell profile or .envrc","Pass -e OPENAI_API_KEY when running containers","Configure CI secrets so jobs inherit the variable","Use a settings-stored key when running GUI-launched processes"],"tags":["environment","api-key","openai","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"}