gitbutlerapp/gitbutler · error

No GitButler token available. Log-in to use the GitButler…

Error message

No GitButler token available. Log-in to use the GitButler OpenAI provider

What it means

Thrown by `gitbutler_proxied_creds` in the OpenAI provider when the GitButler access token cannot be retrieved from the OS secret store (`secret::retrieve(GITBUTLER_ACCESS_TOKEN_HANDLE, ...)` returns Ok(None)). Without a logged-in GitButler account token, the proxied OpenAI endpoint cannot authenticate the user, so the provider raises this error before making any request.

Solutions

  1. Log in to GitButler (via the app or `but login`) so the access token is stored in the OS secret store
  2. If already logged in on another machine, sign in on this one to provision the local token
  3. Fall back to a different credential kind: set OPENAI_API_KEY or configure an own OpenAI key in settings
  4. Verify the OS keychain is accessible/unlocked (e.g. after headless/SSH sessions)

Example fix

// before
$ but ai ...
Error: No GitButler token available. Log-in to use the GitButler OpenAI provider

// after
$ but login
$ but ai ...
Defensive patterns

Strategy: try-catch

Try / catch

match provider_result {
    Err(e) if e.to_string().contains("No GitButler token") => {
        prompt_login(); // run `but login` or open the app's sign-in
    }
    other => other?,
}

Prevention

When it happens

Trigger: Selecting the GitButler-proxied OpenAI provider while the secret store has no entry for the GitButler access token handle — i.e. the user never logged in, logged out, or the token was deleted from the keychain.

Common situations: Fresh install with no GitButler login; using the CLI without `but login`; logging out or clearing keychain entries; secret-store access denied causing a None-style result after migration to a new machine.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/56a6680ace525c47. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-llm/src/openai.rs:84

        }
    }

    /// Configure a custom endpoint if set in the provider, if any.
    fn configure_custom_endpoint(&self, config: OpenAIConfig) -> OpenAIConfig {
        if let Some(custom_endpont) = &self.custom_endpoint {
            config.with_api_base(custom_endpont)
        } else {
            config
        }
    }

    pub fn credentials_kind(&self) -> CredentialsKind {
        self.credentials.0.clone()
    }

    fn gitbutler_proxied_creds() -> Result<(CredentialsKind, Sensitive<String>)> {
        let creds = secret::retrieve(GITBUTLER_ACCESS_TOKEN_HANDLE, secret::Namespace::BuildKind)?
            .ok_or(anyhow::anyhow!(
                "No GitButler token available. Log-in to use the GitButler OpenAI provider"
            ))?;
        Ok((CredentialsKind::GitButlerProxied, creds))
    }

    fn openai_own_key_creds() -> Result<(CredentialsKind, Sensitive<String>)> {
        let creds = secret::retrieve(AI_OPENAI_SECRET_HANDLE, secret::Namespace::Global)?.ok_or(
            anyhow::anyhow!(
                "No OpenAI own key configured. Add this through the GitButler settings"
            ),
        )?;
        Ok((CredentialsKind::OwnOpenAiKey, creds))
    }

    fn openai_env_var_creds() -> Result<(CredentialsKind, Sensitive<String>)> {
        let creds = Sensitive(
            std::env::var_os("OPENAI_API_KEY")
                .ok_or(anyhow::anyhow!(

View on GitHub (pinned to 58e5313667)