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
- Run `but config forge auth` and authenticate against GitLab.
- 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.
- Re-authenticate after wiping or locking the OS keyring so the token is reseeded.
- 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
- Authenticate at app start and after 401s rather than at first GitLab call.
- Keep preferred account ids in sync with authenticated accounts to avoid pointing at tokenless accounts.
- Verify the secret-storage backend works in the environment (headless hosts need a keyring daemon).
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No GitHub access token found for account '{account_id}'. Run
- No authenticated GitLab users found.\nRun 'but config forge
- Preferred GitLab account '{account}' has not authenticated y
- unused
- Failed to get merge request: {}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/fb2939fec34c8958.
Report an issue: GitHub.