gitbutlerapp/gitbutler · error · anyhow::Error

Could not find range from '{}' to '{}' in the displayed file

Error message

Could not find range from '{}' to '{}' in the displayed file list

What it means

The but ID parser accepts range selections like '<start>..<end>' over the file IDs currently displayed. After parsing, both endpoint IDs are looked up in get_all_files_in_display_order; if either endpoint is not in that list, the range cannot be resolved and this error is thrown.

Source

Thrown at crates/but/src/id/parser.rs:173

    // Both sides must resolve to exactly one Uncommitted entity
    if start_matches.len() != 1 || end_matches.len() != 1 {
        return Ok(None);
    }
    if !matches!(&start_matches[0], CliId::UncommittedHunkOrFile(_))
        || !matches!(&end_matches[0], CliId::UncommittedHunkOrFile(_))
    {
        return Ok(None);
    }

    // Valid range — resolve positions in display order
    let all_files = get_all_files_in_display_order(id_map)?;
    let start_pos = all_files.iter().position(|id| id == &start_matches[0]);
    let end_pos = all_files.iter().position(|id| id == &end_matches[0]);

    match (start_pos, end_pos) {
        (Some(s), Some(e)) if s <= e => Ok(Some(all_files[s..=e].to_vec())),
        (Some(s), Some(e)) => Ok(Some(all_files[e..=s].to_vec())),
        _ => Err(anyhow::anyhow!(
            "Could not find range from '{}' to '{}' in the displayed file list",
            parts[0],
            parts[1]
        )),
    }
}

fn get_all_files_in_display_order(id_map: &IdMap) -> anyhow::Result<Vec<CliId>> {
    let mut files: Vec<(&BStr, CliId)> = id_map
        .uncommitted_files
        .values()
        .map(|uncommitted_file| (uncommitted_file.path(), uncommitted_file.to_id()))
        .collect();
    files.sort_by_key(|(a_path, _)| *a_path);

    Ok(files.into_iter().map(|(_, cli_id)| cli_id).collect())
}

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Re-run the listing (e.g. `but status`) to refresh the displayed IDs and redo the selection
  2. Verify both endpoints appear in the current list before using a range
  3. Use individual IDs instead of a range when the list is volatile
Defensive patterns

Strategy: validation

Validate before calling

let ids = get_all_files_in_display_order(&id_map)?;
let endpoints_ok = [start_id, end_id].iter().all(|id| ids.iter().any(|i| i == id));
anyhow::ensure!(endpoints_ok, "range endpoints not in the current file list; re-render");

Try / catch

Treat this error as 'stale selection': re-fetch the current ID list, re-map the user's selection onto fresh IDs, and retry once instead of surfacing the raw error.

Prevention

When it happens

Trigger: Issuing a command with a range argument (e.g. file1..file2) where one endpoint ID does not exist in the current display: a stale ID from an earlier render, a typo, or the file list changed between listing and command.

Common situations: Copy-pasting IDs from an outdated `but status` output; scripts that cache IDs across runs; files staged/hidden between render and command.

Related errors


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