gitbutlerapp/gitbutler · error · anyhow::Error

Preferred Bitbucket account '{account}' has not authenticate

Error message

Preferred Bitbucket account '{account}' has not authenticated yet.
Run 'but config forge auth' to authenticate, or choose another account.

What it means

resolve_account() bails when the caller explicitly passed a preferred_account (a BitbucketAccountIdentifier) that is not present in list_known_bitbucket_accounts(storage). The default account path is deliberately skipped — only a mismatched explicit selection fails. The message suggests either authenticating that account or choosing another one.

Source

Thrown at crates/but-bitbucket/src/client.rs:634

        ))
    }
}

pub(crate) fn resolve_account(
    preferred_account: Option<&crate::BitbucketAccountIdentifier>,
    storage: &but_forge_storage::Controller,
) -> Result<crate::BitbucketAccountIdentifier, anyhow::Error> {
    let known_accounts = crate::token::list_known_bitbucket_accounts(storage)?;
    let Some(default_account) = known_accounts.first() else {
        bail!(
            "No authenticated Bitbucket users found.\nRun 'but config forge auth' to authenticate with Bitbucket."
        );
    };
    let account = if let Some(account) = preferred_account {
        if known_accounts.contains(account) {
            account
        } else {
            bail!(
                "Preferred Bitbucket account '{account}' has not authenticated yet.\nRun 'but config forge auth' to authenticate, or choose another account."
            );
        }
    } else {
        default_account
    };

    Ok(account.to_owned())
}

/// Escape a value for embedding inside a double-quoted Bitbucket query-language
/// string, so a branch name with quotes/backslashes can't break or inject into
/// the query.
fn escape_bbql(value: &str) -> String {
    value.replace('\\', "\\\\").replace('"', "\\\"")
}

/// BBQL predicate matching pull requests in any state targeting `target_branch`.

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Run 'but config forge auth' and authenticate specifically as that account
  2. Or drop the preferred-account override so resolve_account falls back to the default (first known) account
  3. Verify the identifier matches exactly what token storage recorded (list_known_bitbucket_accounts)
  4. Remove the stale account reference from the config that is injecting it
Defensive patterns

Strategy: validation

Validate before calling

let known = but_bitbucket::token::list_known_bitbucket_accounts(storage)?;
if let Some(preferred) = &requested {
    anyhow::ensure!(known.contains(preferred),
        "account {preferred} not authenticated; known: {known:?}");
}

Try / catch

// fall back to the default account when the pinned one is unknown
match resolve_account(Some(&preferred), storage) {
    Err(e) if e.to_string().contains("has not authenticated yet") =>
        resolve_account(None, storage)?, // or prompt re-auth
    r => r?,
}

Prevention

When it happens

Trigger: Passing an account id/username that authenticated on a different machine or was logged out since; multi-account setups where the caller pins an account by stale config; case/format differences between the stored identifier and the requested one.

Common situations: Team configs pinning an account name after the member re-authenticated under a different username; copied dotfiles/config between machines; account removed via auth management but still referenced in repo-level forge settings.

Understand the failure class

Related errors


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