gitbutlerapp/gitbutler · error · anyhow::Error
Could not find {kind} CLI id '{short_id}' in IdMap
Error message
Could not find {kind} CLI id '{short_id}' in IdMap What it means
Thrown by `lookup_cli_id_for_short_id` (used by TUI/status commands): the short id string is parsed against the IdMap, matches are kept only if their canonical `to_short_string()` equals the input and they pass a kind predicate (e.g. commit vs branch). Zero surviving matches produces this error — the id is not registered for that kind.
Source
Thrown at crates/but/src/command/legacy/status/mod.rs:1852
]),
)?;
}
Ok(())
}
fn lookup_cli_id_for_short_id(
id_map: &IdMap,
repo: &gix::Repository,
short_id: &str,
predicate: impl Fn(&CliId) -> bool,
kind: &str,
) -> anyhow::Result<CliId> {
let mut matches = id_map.parse_using_repo(short_id, repo)?;
matches.retain(|id| id.to_short_string() == short_id && predicate(id));
match matches.len() {
1 => Ok(matches.remove(0)),
0 => Err(anyhow::anyhow!(
"Could not find {kind} CLI id '{short_id}' in IdMap"
)),
_ => Err(anyhow::anyhow!(
"CLI id '{short_id}' is ambiguous for {kind} in IdMap"
)),
}
}
fn status_letter(status: &TreeStatus) -> char {
match status {
TreeStatus::Addition { .. } => 'A',
TreeStatus::Deletion { .. } => 'D',
TreeStatus::Modification { .. } => 'M',
TreeStatus::Rename { .. } => 'R',
}
}
pub fn status_letter_ui(status: &ui::TreeStatus) -> char {View on GitHub (pinned to caf1f223d3)
Solutions
- Rerun `but status` (or the list command for that kind) and copy a fresh short id
- Double-check the id kind matches what the command expects (commit id for commit commands, branch id for branch commands)
- Use the full-length git sha where the command accepts it — it bypasses short-id ambiguity and staleness
- Retype the id carefully; a single wrong character makes the exact-string match fail
Example fix
# before: id from yesterday's output but <cmd> c7 # after: refresh and use current ids but status but <cmd> c4 # id as printed just now
Defensive patterns
Strategy: validation
Validate before calling
let matches = id_map.parse_using_repo(short_id, repo)?;
let hits: Vec<_> = matches
.into_iter()
.filter(|id| id.to_short_string() == short_id && kind_predicate(id))
.collect();
if hits.is_empty() {
anyhow::bail!("no {kind} id '{short_id}'; refresh with 'but status' and copy a current id");
} Try / catch
match lookup_cli_id_for_short_id(id_map, repo, short_id, |i| is_commit(i), "commit") {
Ok(cli_id) => { /* use */ }
Err(err) if err.to_string().contains("Could not find") => {
// re-list ids and retry with a fresh one
}
Err(err) => return Err(err),
} Prevention
- Always take ids from the latest `but status` output; never reuse them after amend/rebase/ship
- Check that the id kind matches the command (commit id vs branch id)
- Prefer full shas in long-running scripts to avoid stale short ids
When it happens
Trigger: Passing a short id copied from stale `but status` output after ids shifted; a typo in the short id; passing a commit id where the command's predicate only accepts another kind, filtering out the real match.
Common situations: Piping ids between invocations across a rebase/amend/ship that renumbered them; reusing ids from a different workspace or project; scripts holding on to ids for too long.
Related errors
- CLI id '{short_id}' is ambiguous for {kind} in IdMap
- Commit '{commit_id_str}' not found
- Editor exited with non-zero status
- The repository at {} is bare. GitButler requires a non-bare
- The repository at {} is a non-main worktree. GitButler requi
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/4de78751220c6efe.
Report an issue: GitHub.