{"record":{"id":"d5d04b7fb750470d","repo":"gitbutlerapp/gitbutler","slug":"no-openai-own-key-configured-add-this-through-the","errorCode":null,"errorMessage":"No OpenAI own key configured. Add this through the GitButler settings","messagePattern":"No OpenAI own key configured\\. Add this through the GitButler settings","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-llm/src/openai.rs","lineNumber":92,"sourceCode":"            config\n        }\n    }\n\n    pub fn credentials_kind(&self) -> CredentialsKind {\n        self.credentials.0.clone()\n    }\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 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}","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-llm/src/openai.rs#L74-L110","documentation":"Thrown by `openai_own_key_creds` when `secret::retrieve(AI_OPENAI_SECRET_HANDLE, Namespace::Global)` returns Ok(None) — the OS secret store holds no stored OpenAI key under GitButler's handle. This credential kind is only used when the user explicitly configured their own OpenAI key, so an absent entry means the stored key was never created or has since been removed.","triggerScenarios":"Credential resolution selects the own-key path (`openai_own_key_creds`) but no key was ever saved under AI_OPENAI_SECRET_HANDLE — e.g. settings entry cleared, keychain entry deleted externally, or a fresh profile/machine without re-entering the key.","commonSituations":"User toggled to \"use my own OpenAI key\" mode without saving the key; OS keychain wiped or reset; migrating machines without re-entering secrets; a settings sync that changed the mode but not the secret.","solutions":["Open GitButler settings and add/save your OpenAI API key","Alternatively export OPENAI_API_KEY so the env-var credential path can be used","Or switch back to the GitButler-proxied provider after logging in","Check the OS keychain (Keychain Access / GNOME Keyring / Windows Credential Manager) for an accidentally deleted GitButler entry"],"exampleFix":"// before: settings.json has mode \"own\" but no key stored\n// after: save key via settings UI, or\n$ export OPENAI_API_KEY=sk-proj-...","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if let Err(e) = result {\n    if e.to_string().contains(\"No OpenAI own key\") {\n        eprintln!(\"Add your OpenAI key in GitButler settings or export OPENAI_API_KEY\");\n    }\n}","preventionTips":["Save the own-key in settings at the same time you switch the provider mode","After reinstalling or migrating machines, re-enter stored secrets","Don't delete keychain entries related to GitButler during keychain cleanups","Keep OPENAI_API_KEY as a fallback in dev environments"],"tags":["credentials","api-key","openai","configuration"],"backgroundTag":"missing-credentials","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"}