gastownhall/beads · error
failed to fingerprint target changes: %w
Error message
failed to fingerprint target changes: %w
What it means
To detect uncommitted changes, bd hashes the contents of every path reported dirty by `git status --porcelain=v1 -z`. This error wraps failures from walking/hashing those changed files (permissions, concurrent deletion, stat errors) — missing files are tolerated (`<missing>`), but other I/O failures abort.
Source
Thrown at cmd/bd/worktree_cmd.go:1036
gitMarkerPath := filepath.Join(worktree.path, ".git")
gitMarkerInfo, err := os.Lstat(gitMarkerPath)
if err != nil {
return pinnedWorktreeTarget{}, fmt.Errorf("failed to pin target git marker identity: %w", err)
}
if gitMarkerInfo.Mode()&os.ModeSymlink != 0 || !gitMarkerInfo.Mode().IsRegular() {
return pinnedWorktreeTarget{}, fmt.Errorf("target git marker is not a regular file: %s", gitMarkerPath)
}
gitDirFingerprint, err := fingerprintWorktreeFilesystem(gitDir)
if err != nil {
return pinnedWorktreeTarget{}, fmt.Errorf("failed to fingerprint target git directory: %w", err)
}
gitMarkerFingerprint, err := fingerprintWorktreeFilesystem(gitMarkerPath)
if err != nil {
return pinnedWorktreeTarget{}, fmt.Errorf("failed to fingerprint target git marker: %w", err)
}
statusFingerprint, err := fingerprintWorktreeStatusPaths(worktree.path, string(statusOutput))
if err != nil {
return pinnedWorktreeTarget{}, fmt.Errorf("failed to fingerprint target changes: %w", err)
}
return pinnedWorktreeTarget{
path: filepath.Clean(worktree.path),
pathInfo: pathInfo,
gitDir: gitDir,
gitDirInfo: gitDirInfo,
gitMarkerInfo: gitMarkerInfo,
gitDirFingerprint: gitDirFingerprint,
gitMarkerFingerprint: gitMarkerFingerprint,
commonDir: filepath.Clean(strings.TrimSpace(string(commonDirOutput))),
headOID: headOID,
branch: worktree.branch,
detached: worktree.detached,
bare: worktree.bare,
locked: worktree.locked,
lockReason: worktree.lockReason,
prunable: worktree.prunable,View on GitHub (pinned to 71377f2769)
Solutions
- Fix read permissions on the changed files: `chmod -R u+rwX <worktree>`
- Commit or discard the changes first (`git add -A && git commit` or `git checkout -- .`), then remove with a clean status
- If you accept data loss, use the force flag to bypass the cleanliness fingerprint entirely
Example fix
// before: unreadable modified file blocks fingerprint chmod u+rw src/main.go // after bd worktree remove mywt
Defensive patterns
Strategy: validation
Validate before calling
// every dirty path should be readable before removal
out, _ := exec.Command("git", "-C", wt, "status", "--porcelain=v1", "-z").Output()
for _, p := range strings.Split(string(out), "\x00") {
if len(p) > 3 {
if _, err := os.Stat(filepath.Join(wt, p[3:])); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("unreadable changed file %s: %w", p[3:], err)
}
}
} Prevention
- Commit or stash changes before worktree removal to keep the dirty set empty
- Ensure all repo files are readable by the user running bd
- Use the force flag only when you accept losing unreadable local changes
When it happens
Trigger: `bd worktree remove <name>` without --force when a modified/untracked file listed by `git status` cannot be read: permission denied, unreadable symlink target handling, or transient I/O failures during the walk.
Common situations: Root-owned or 000-permission modified files; files locked by another process (Windows editors, AV); sparse-checkout entries with odd permissions; FUSE mount errors on untracked files.
Related errors
- failed to fingerprint target git directory: %w
- failed to fingerprint target git marker: %w
- git push (delete %s) failed: %s: %w
- failed to check git index lock %s: %w
- failed to read .gitignore: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/76535447e3419c19.
Report an issue: GitHub.