gitbutlerapp/gitbutler · error

repo access failed

Error message

repo access failed

What it means

Panic during 'but setup' when initializing a brand-new repository: create_empty_initial_commit calls head_tree_id_or_empty, which for an unborn HEAD returns the well-known empty-tree id but still has to read HEAD through the refdb. The expect ('repo access failed') fires when that read fails - a corrupted or unreadable .git, a HEAD pointing at an unreadable ref, or a concurrent process deleting the repository mid-setup.

Source

Thrown at crates/but/src/command/legacy/setup.rs:656

            create_empty_initial_commit(&repo)?;

            writeln!(
                &mut progress as &mut dyn FmtWrite,
                "{}",
                t.success
                    .paint("Initialized a new repository and created an empty first commit.\n")
            )?;
            return Ok(repo);
        }
    }

    Err(anyhow::anyhow!("No git repository found."))
}

fn create_empty_initial_commit(repo: &gix::Repository) -> anyhow::Result<()> {
    // In an unborn repo, this returns the well-known empty-tree id.
    // (It works even if the empty tree object isn’t physically in the ODB.)
    let empty_tree = repo.head_tree_id_or_empty().expect("repo access failed"); // -> Id<'_>
    let empty_tree = empty_tree.detach(); // -> ObjectId (optional; commit() accepts Into<ObjectId> anyway)

    // No parents for the first commit. Update HEAD (writes through to refs/heads/main).
    repo.commit(
        "HEAD",
        "Initial empty commit\n",
        empty_tree,
        std::iter::empty::<gix::hash::ObjectId>(),
    )?;

    Ok(())
}

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Check repository integrity in the same directory: 'git fsck'
  2. Verify read/write permissions on .git for the running user
  3. If .git is a broken remnant, delete it and re-run 'git init' followed by 'but setup'
  4. Avoid running other git processes against the repo during setup

Example fix

// before
let empty_tree = repo.head_tree_id_or_empty().expect("repo access failed");

// after
let empty_tree = repo.head_tree_id_or_empty()
    .map_err(|e| anyhow::anyhow!("cannot read HEAD while creating the initial commit: {e}"))?;
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight before setup writes anything: HEAD must be readable
if repo.find_reference("HEAD").is_err() {
    anyhow::bail!(".git is not readable - check permissions or run 'git fsck'");
}

Prevention

When it happens

Trigger: Running 'but setup' in a directory whose .git was partially created or corrupted (interrupted git init); filesystem permissions denying reads under .git; antivirus/file locking on Windows removing or locking files mid-run; another process deleting the repo concurrently.

Common situations: Interrupted repository initialization; restored-from-backup clones with damaged refs; sandboxed environments blocking .git access; running setup while another git process rewrites refs.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/1967abf3ff11980b. Report an issue: GitHub.