gitbutlerapp/gitbutler · error · anyhow::Error
Preferred GitLab account '{account}' has not authenticated y
Error message
Preferred GitLab account '{account}' has not authenticated yet.\nRun 'but config forge auth' to authenticate, or choose another account. What it means
Thrown by resolve_account when a preferred GitLab account was explicitly requested but it is not among the accounts known to but-forge storage. The identifier is compared against the token store's account list; any mismatch — typo, different casing/format, or the account simply never completed auth on this machine — bails. Unlike the no-accounts error, valid accounts exist; the requested one just is not one of them.
Source
Thrown at crates/but-gitlab/src/client.rs:1087
let target_project_id = target_project_id.unwrap_or(project_id);
source_project_id != target_project_id
}
pub(crate) fn resolve_account(
preferred_account: Option<&crate::GitlabAccountIdentifier>,
storage: &but_forge_storage::Controller,
) -> Result<crate::GitlabAccountIdentifier, anyhow::Error> {
let known_accounts = crate::token::list_known_gitlab_accounts(storage)?;
let Some(default_account) = known_accounts.first() else {
bail!(
"No authenticated GitLab users found.\nRun 'but config forge auth' to authenticate with GitLab."
);
};
let account = if let Some(account) = preferred_account {
if known_accounts.contains(account) {
account
} else {
bail!(
"Preferred GitLab account '{account}' has not authenticated yet.\nRun 'but config forge auth' to authenticate, or choose another account."
);
}
} else {
default_account
};
Ok(account.to_owned())
}
#[cfg(test)]
mod tests {
use super::{
GitLabMergeRequest, GitLabPipelineJob, GitLabPipelineRef, MAX_MERGE_REQUEST_REQUESTS,
MergeRequest, merge_request_page_is_safe, next_page_from_headers, normalize_pipeline_jobs,
repo_owner_from_path_with_namespace, update_draft_state_in_title,
};
use reqwest::header::{HeaderMap, HeaderValue};View on GitHub (pinned to caf1f223d3)
Solutions
- Run `but config forge auth` and authenticate specifically as that account, then retry
- List the authenticated accounts and use one of those identifiers instead (or pass None to take the default)
- If the GitLab account name/email changed, re-auth to refresh the stored identifier and update the preference to match
- Check for casing/whitespace differences between the preferred identifier and the stored one
Example fix
// before
let account = resolve_account(Some(&preferred), &storage)?; // unknown handle aborts
// after: fall back to the default account with a warning
let account = match resolve_account(Some(&preferred), &storage) {
Ok(account) => account,
Err(err) if err.to_string().contains("has not authenticated yet") => {
tracing::warn!(%preferred, "account not authenticated; using default");
resolve_account(None, &storage)?
}
Err(err) => return Err(err),
}; Defensive patterns
Strategy: validation
Validate before calling
// Validate the preferred account against the store before calling Git APIs
let known = but_gitlab::token::list_known_gitlab_accounts(&storage)?;
let account = match preferred_account.filter(|a| known.contains(a)) {
Some(a) => a.clone(),
None => known.first().cloned().context("no GitLab accounts authenticated")?, // fall back to default
}; Try / catch
match resolve_account(Some(&preferred), &storage) {
Ok(account) => Ok(account),
Err(err) if err.to_string().contains("has not authenticated yet") => {
tracing::warn!(%preferred, "not authenticated; falling back to default account");
resolve_account(None, &storage)
}
Err(err) => Err(err),
} Prevention
- Persist the account identifier exactly as `but config forge auth` stored it (watch casing and email vs username)
- After renaming a GitLab account, re-auth and update saved preferences
When it happens
Trigger: Calling a GitLab API with preferred_account = Some(&identifier) where identifier is a handle that never ran `but config forge auth` on this machine; the account's name/email changed on GitLab so the stored identifier differs from the configured one; configuration copied between machines that authenticated different accounts; casing or formatting mismatch in the stored preference.
Common situations: Multi-account users (work + personal) with a stale default in settings; dotfiles/config synced across machines where only one machine authenticated the second account; rename on GitLab.com breaking a stored identifier.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No authenticated GitLab users found.\nRun 'but config forge
- No GitLab access token found for account '{account_id}'. Run
- Preferred Bitbucket account '{account}' has not authenticate
- Preferred GitHub account '{account}' has not authenticated y
- Failed to get merge request: {}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/877b2fa2b607a999.
Report an issue: GitHub.