gitbutlerapp/gitbutler · error
Username ambiguous, got
Error message
Username ambiguous, got {accounts_to_delete:?} What it means
`but config forge forget` matches the given username against known forge accounts. If the pattern matches multiple accounts, the CLI would normally prompt the user to pick one interactively; but if the output channel cannot provide terminal input (piped stdout, non-TTY, or embedded usage), it cannot disambiguate and bails, printing the ambiguous account list.
Solutions
- Pass the exact, full username of the single account to forget so the match is unambiguous
- Run the command in an interactive terminal so the selection prompt can be shown
- List accounts first with `but config forge list-users` to find the exact username
Example fix
// before but config forge forget john | tee log # matches john@a and john@b // after but config forge forget john@acmecorp
Defensive patterns
Strategy: validation
Validate before calling
async function resolveUniqueAccount(pattern) {
const users = (await exec('but config forge list-users')).stdout.split('\n').filter(Boolean);
const matches = users.filter(u => u.includes(pattern));
if (matches.length !== 1) throw new Error(`Pattern matches ${matches.length} accounts: ${matches}`);
return matches[0];
} Type guard
const isUniqueMatch = (matches) => Array.isArray(matches) && matches.length === 1;
Try / catch
try {
await exec(`but config forge forget ${exactUsername}`);
} catch (e) {
if (e.message.includes('Username ambiguous')) {
console.error('Pass the exact username; see list-users output in the error');
} else throw e;
} Prevention
- Pass full exact usernames, not prefixes, when stdout is not a TTY
- Run `but config forge list-users` first to disambiguate
- Avoid renaming/colliding account names across forges
When it happens
Trigger: Running `but config forge forget <pattern>` where the name/pattern matches two or more stored forge accounts AND stdout is not an interactive terminal (prepare_for_terminal_input returns None), e.g. in scripts or CI.
Common situations: Two GitHub accounts stored (work + personal) with a partial-name pattern matching both; running the forget command from a script with redirected output; CI pipelines cleaning up forge credentials.
Related errors
- Ambiguous branch ' ', matches multiple items
- Ambiguous branch identifier
- CLI id ' ' is ambiguous for in IdMap
- Commit ID ' ' is ambiguous. Please provide more characters…
- Commit ID ' ' is ambiguous. Found matches
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/0b7ed4b67896d199.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but/src/command/config.rs:1308
if let Some((username, out)) = username.zip(out.for_human()) {
writeln!(out, "No known forge account matching '{username}'")?;
}
return Ok(());
}
// Handle different scenarios based on number of accounts
match accounts_to_delete.as_slice() {
[single_account] => {
// Single account: delete automatically
forget_account(single_account)?;
if let Some(out) = out.for_human() {
writeln!(out, "Forgot forge account '{single_account}'")?;
}
}
_ => {
// Multiple accounts: prompt user to select
let Some(mut input) = out.prepare_for_terminal_input() else {
anyhow::bail!("Username ambiguous, got {accounts_to_delete:?}");
};
let account_options = accounts_to_delete
.into_iter()
.map(|account| (account.to_string(), account))
.collect::<Vec<_>>();
let account_options = nonempty::NonEmpty::from_vec(account_options)
.context("No accounts available to forget")?;
let selected_accounts = input
.prompt_multi_select(
"Which of the following accounts do you want to forget?",
&account_options,
)?
.ok_or_else(|| anyhow::anyhow!("Could not determine which accounts to delete"))?;
if selected_accounts.is_empty() {
writeln!(input, "No accounts were selected to forget.")?;
return Ok(());View on GitHub (pinned to 58e5313667)