gastownhall/beads · error
failed to pin target directory identity: %w
Error message
failed to pin target directory identity: %w
What it means
After HEAD verification, inspectWorktreeTarget calls os.Lstat on the worktree path to pin its on-disk identity. If Lstat fails — the path does not exist or is unreadable — this wrapped error is returned. Removal cannot proceed because the target directory cannot be identified.
Source
Thrown at cmd/bd/worktree_cmd.go:1006
"--untracked-files=all",
"--ignore-submodules=none",
"--ignored=matching",
)
if err != nil {
return pinnedWorktreeTarget{}, fmt.Errorf("failed to inspect target cleanliness: %w", err)
}
headOID := strings.TrimSpace(string(headOutput))
if headOID == "" || headOID != worktree.headOID {
return pinnedWorktreeTarget{}, fmt.Errorf(
"target HEAD disagrees with git worktree registry (registry %q, target %q)",
worktree.headOID,
headOID,
)
}
pathInfo, err := os.Lstat(worktree.path)
if err != nil {
return pinnedWorktreeTarget{}, fmt.Errorf("failed to pin target directory identity: %w", err)
}
if pathInfo.Mode()&os.ModeSymlink != 0 || !pathInfo.IsDir() {
return pinnedWorktreeTarget{}, fmt.Errorf("target path is not a real directory: %s", worktree.path)
}
gitDirInfo, err := os.Lstat(gitDir)
if err != nil {
return pinnedWorktreeTarget{}, fmt.Errorf("failed to pin target git directory identity: %w", err)
}
if gitDirInfo.Mode()&os.ModeSymlink != 0 || !gitDirInfo.IsDir() {
return pinnedWorktreeTarget{}, fmt.Errorf("target git directory is not a real directory: %s", gitDir)
}
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)View on GitHub (pinned to 71377f2769)
Solutions
- Confirm the directory exists with `ls <path>`; if gone, run `git worktree prune` and clean the bd registry entry instead of removing.
- If the path moved, update the registration to the new path and retry.
- Restore access to the parent directory or remount the volume, then retry.
- Stop any racing process that deletes the directory mid-operation.
Example fix
// before bd worktree remove feature-x // error: failed to pin target directory identity: lstat ...: no such file or directory // after git worktree prune bd worktree list # entry gone; nothing to remove
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, statSync } from "node:fs";
if (!existsSync(worktreePath) || !statSync(worktreePath).isDirectory()) {
throw new Error("worktree directory missing — prune registry instead of removing");
} Prevention
- Use `git worktree remove`/`bd worktree remove` instead of rm -rf.
- Exclude worktree paths from aggressive cleanup scripts.
- Remount network volumes before operating on worktrees.
- Reconcile the registry after any manual directory moves.
When it happens
Trigger: The registered worktree directory was deleted or renamed after registry listing but before inspection; a race where another process removes the directory between listing and Lstat; permission denied on a parent directory; revalidation on a vanished directory.
Common situations: Manual `rm -rf` of a worktree without `git worktree remove`; a build/CI cleaner deleting stale directories; unmounted network volume making the path temporarily disappear; moved path in the registry.
Related errors
- failed to get current directory: %w
- failed to pin target git directory identity: %w
- target git directory is not a real directory: %s
- failed to pin target git marker identity: %w
- cannot safely prepare .gitignore cleanup: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a5948dfc76f49d78.
Report an issue: GitHub.