gitbutlerapp/gitbutler · error · anyhow::Error

No GitLab access token found for account '{account_id}'. Run

Error message

No GitLab access token found for account '{account_id}'.
Run 'but config forge auth' to re-authenticate.

What it means

`GitLabClient::from_storage` resolves an account (preferred identifier or stored default) and fetches its access token from OS secret storage via `but_gitlab::token::get_gl_access_token`. A `None` result means no client can be built, and this error is returned with the remediation hint `but config forge auth`.

Source

Thrown at crates/but-gitlab/src/client.rs:79

            .default_headers(headers)
            .timeout(GITLAB_REQUEST_TIMEOUT)
            .build()?;

        Ok(Self {
            client,
            base_url: GITLAB_API_BASE_URL.to_string(),
        })
    }

    pub fn from_storage(
        storage: &but_forge_storage::Controller,
        preferred_account: Option<&crate::GitlabAccountIdentifier>,
    ) -> anyhow::Result<Self> {
        let account_id = resolve_account(preferred_account, storage)?;
        if let Some(access_token) = crate::token::get_gl_access_token(&account_id, storage)? {
            account_id.client(&access_token)
        } else {
            Err(anyhow::anyhow!(
                "No GitLab access token found for account '{account_id}'.\nRun 'but config forge auth' to re-authenticate."
            ))
        }
    }

    pub fn new_with_host_override(access_token: &Sensitive<String>, host: &str) -> Result<Self> {
        let mut headers = HeaderMap::new();
        headers.insert(
            USER_AGENT,
            HeaderValue::from_static("gb-gitlab-integration"),
        );
        headers.insert(ACCEPT, HeaderValue::from_static("application/json"));
        headers.insert(
            AUTHORIZATION,
            HeaderValue::from_str(&format!("Bearer {}", access_token.0))?,
        );

        let client = reqwest::Client::builder()

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Run `but config forge auth` and authenticate against GitLab.
  2. Confirm the resolved account is the one that holds the token — a stale `preferred_account` id for a never-authenticated account triggers this even with other valid accounts present.
  3. Re-authenticate after wiping or locking the OS keyring so the token is reseeded.
  4. Ensure a secret-service backend is available in headless environments.

Example fix

// before
let client = GitLabClient::from_storage(&storage, preferred_account)?;

// after
let client = match GitLabClient::from_storage(&storage, preferred_account) {
    Ok(client) => client,
    Err(e) if e.to_string().contains("No GitLab access token") => {
        prompt_reauth().await?; // equivalent of `but config forge auth`
        GitLabClient::from_storage(&storage, preferred_account)?
    }
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: try-catch

Validate before calling

use but_gitlab::token::get_gl_access_token;

// Pre-check before building a client / firing a request
if get_gl_access_token(&account_id, &storage).ok().flatten().is_none() {
    // route the user to `but config forge auth` instead of failing mid-call
}

Try / catch

match but_gitlab::GitLabClient::from_storage(&storage, preferred_account) {
    Ok(client) => client,
    Err(e) if e.to_string().contains("No GitLab access token") => {
        // start the re-auth flow; the error message already names the command
        anyhow::bail!("GitLab authentication required: {e}");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Any but-gitlab operation that builds a client from storage while no GitLab token exists for the resolved `account_id` — after logout, on a new machine, when the token was deleted or revoked, or when the preferred account never authenticated.

Common situations: Fresh installs; keyring reset or locked; GitLab tokens revoked in profile settings; self-hosted GitLab instances where the account was registered but OAuth never completed; headless CI hosts without a secret store.

Understand the failure class

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/fb2939fec34c8958. Report an issue: GitHub.