gitbutlerapp/gitbutler · error · anyhow::Error

Failed to resolve path to hunk

Error message

Failed to resolve path to hunk

What it means

`but open` maps a selected uncommitted hunk to a file/line location via repo.workdir_path(hunk.path). That helper returns None when the repository has no working directory, so the hunk's repository-relative path cannot be made absolute and opening is refused.

Source

Thrown at crates/but/src/command/open.rs:53

#[derive(Debug)]
pub(crate) enum Openable {
    File(PathBuf),
    Files(NonEmpty<PathBuf>),
    Hunk(Hunk),
}

impl Openable {
    /// Try to create an [`Openable`] from an [`UncommittedHunkOrFile`].
    pub fn try_from_uncommitted(
        repo: &gix::Repository,
        uncommitted: &UncommittedHunkOrFile,
    ) -> anyhow::Result<Self> {
        let hunk = &uncommitted.hunks.first().hunk;

        let path = repo
            .workdir_path(hunk.path.as_bstr())
            .ok_or_else(|| anyhow::anyhow!("Failed to resolve path to hunk"))?;

        let openable = match (
            uncommitted.is_entire_file,
            &hunk.hunk_header,
            hunk.line_nums(),
        ) {
            (false, Some(hunk_header), Some((line_nums_added, line_nums_removed))) => {
                Openable::Hunk(Hunk {
                    // Truncate line numbers - the probability of exceeding a u32 is infinitesimally small.
                    line_nums_added: line_nums_added
                        .iter()
                        .map(|n| (*n).min(u32::MAX as usize) as u32)
                        .collect(),
                    line_nums_removed: line_nums_removed
                        .iter()
                        .map(|n| (*n).min(u32::MAX as usize) as u32)
                        .collect(),
                    old_start: hunk_header.old_start,

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Restart but from the directory containing the working copy (`git rev-parse --show-toplevel` shows it)
  2. Confirm the repo is not bare: `git rev-parse --is-bare-repository` must print false
  3. If the worktree moved, restart the session so hunk paths are re-resolved
Defensive patterns

Strategy: validation

Validate before calling

let repo = ctx.repo.get()?;
anyhow::ensure!(
    repo.workdir().is_some(),
    "cannot open hunks without a working directory"
);

Prevention

When it happens

Trigger: Invoking `but open` (or Openable::try_from_uncommitted) on an uncommitted hunk while the opened repository is bare, typically because but was started from a bare clone or from the gitdir side of a linked worktree.

Common situations: Running the TUI from a .git directory or worktree admin dir; the worktree was removed or moved while a TUI session was still open.

Related errors


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