gitbutlerapp/gitbutler · error

No ID found for entity

Error message

No ID found for entity

What it means

handle_tui builds the TUI diff viewer from an optional target string: it runs IdMap::parse_using_context on the entity and takes the first parsed ID. This error fires when parsing succeeds but yields an empty list — the given string matches no known ID/hunk/path entity in the current ID map. (The TODO in the sibling handle() notes plain-name lookup and ambiguity handling are known gaps.)

Source

Thrown at crates/but/src/command/legacy/diff/mod.rs:25

    id::{CommitId, CommittedFileId},
    utils::OutputChannel,
    utils::change_source::ChangeSourceId,
};

mod display;
mod show;

pub fn handle_tui(ctx: &mut Context, target_str: Option<&str>) -> anyhow::Result<()> {
    use crate::tui::diff_viewer::{DiffFileEntry, WorktreeFilter};

    let id_map = IdMap::legacy_new_from_context(ctx)?;

    let files = if let Some(entity) = target_str {
        let id = id_map
            .parse_using_context(entity, ctx)?
            .first()
            .cloned()
            .ok_or_else(|| anyhow::anyhow!("No ID found for entity"))?;

        match id {
            CliId::UncommittedHunkOrFile(ref uncommitted_id) => {
                let filter = WorktreeFilter::Uncommitted(Box::new(uncommitted_id.clone()));
                DiffFileEntry::from_worktree(&id_map, Some(&filter))
            }
            CliId::PathPrefix { hunks, .. } => DiffFileEntry::from_hunks(&hunks),
            CliId::Uncommitted { .. } => DiffFileEntry::from_worktree(
                &id_map,
                Some(&WorktreeFilter::Source(ChangeSourceId::Head)),
            ),
            CliId::Worktree { name, .. } => DiffFileEntry::from_worktree(
                &id_map,
                Some(&WorktreeFilter::Source(ChangeSourceId::Worktree(name))),
            ),
            CliId::Stack { .. } => DiffFileEntry::from_worktree(
                &id_map,
                Some(&WorktreeFilter::Source(ChangeSourceId::Head)),

View on GitHub (pinned to caf1f223d3)

Solutions

  1. List valid IDs first with `but id` and retry with one of those exact/prefix selectors.
  2. Prefer path-prefix selectors (a dirty file's path) which are stable across ID-map rebuilds.
  3. Run without a target to open the whole worktree diff and navigate interactively.

Example fix

# before
$ but diff tui 4c
Error: No ID found for entity

# after
$ but id   # find a live ID
$ but diff tui 4c1e
Defensive patterns

Strategy: validation

Validate before calling

// Resolve the entity before launching the TUI
let id_map = IdMap::legacy_new_from_context(ctx)?;
if let Some(entity) = target_str {
    anyhow::ensure!(
        !id_map.parse_using_context(entity, ctx)?.is_empty(),
        "'{entity}' matches no known change; run `but id` for valid selectors"
    );
}

Prevention

When it happens

Trigger: Launching the diff TUI with a stale or mistyped selector: `but diff tui abc123` where abc123 names no worktree hunk, path prefix, or branch/worktree in the current IdMap.

Common situations: Selector copied from an earlier session whose worktree changes were committed/discarded; using plain branch names that the parser doesn't resolve (per the TODO); abbreviations too short to match any entry.

Related errors


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