{"record":{"id":"cd727ba3a4773345","repo":"gastownhall/beads","slug":"target-git-directory-is-not-a-real-directory-s","errorCode":null,"errorMessage":"target git directory is not a real directory: %s","messagePattern":"target git directory is not a real directory: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/worktree_cmd.go","lineNumber":1016,"sourceCode":"\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\n\t\t\t\"target HEAD disagrees with git worktree registry (registry %q, target %q)\",\n\t\t\tworktree.headOID,\n\t\t\theadOID,\n\t\t)\n\t}\n\tpathInfo, err := os.Lstat(worktree.path)\n\tif err != nil {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"failed to pin target directory identity: %w\", err)\n\t}\n\tif pathInfo.Mode()&os.ModeSymlink != 0 || !pathInfo.IsDir() {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"target path is not a real directory: %s\", worktree.path)\n\t}\n\tgitDirInfo, err := os.Lstat(gitDir)\n\tif err != nil {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"failed to pin target git directory identity: %w\", err)\n\t}\n\tif gitDirInfo.Mode()&os.ModeSymlink != 0 || !gitDirInfo.IsDir() {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"target git directory is not a real directory: %s\", gitDir)\n\t}\n\tgitMarkerPath := filepath.Join(worktree.path, \".git\")\n\tgitMarkerInfo, err := os.Lstat(gitMarkerPath)\n\tif err != nil {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"failed to pin target git marker identity: %w\", err)\n\t}\n\tif gitMarkerInfo.Mode()&os.ModeSymlink != 0 || !gitMarkerInfo.Mode().IsRegular() {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"target git marker is not a regular file: %s\", gitMarkerPath)\n\t}\n\tgitDirFingerprint, err := fingerprintWorktreeFilesystem(gitDir)\n\tif err != nil {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"failed to fingerprint target git directory: %w\", err)\n\t}\n\tgitMarkerFingerprint, err := fingerprintWorktreeFilesystem(gitMarkerPath)\n\tif err != nil {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"failed to fingerprint target git marker: %w\", err)\n\t}\n\tstatusFingerprint, err := fingerprintWorktreeStatusPaths(worktree.path, string(statusOutput))","sourceCodeStart":998,"sourceCodeEnd":1034,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/worktree_cmd.go#L998-L1034","documentation":"Before removing a worktree, bd pins the filesystem identity of the target's git directory (the worktree's private .git dir under .git/worktrees/). This error means `os.Lstat` on that directory succeeded, but it is a symlink or not a directory. bd refuses to fingerprint/remove a target whose gitdir is not a plain directory, because identity pinning and hashing would be unreliable.","triggerScenarios":"Running `bd worktree remove` (prepareWorktreeRemoval) or a revalidation (observeRevalidation) when the resolved gitdir path is a symlink, was replaced by a file, or the worktree registry points at a stale/corrupted gitdir path.","commonSituations":"Moving the repository with symlinks in .git/worktrees; manual edits to .git/worktrees/<name>/gitdir; restoring a repo from backup that turned gitdirs into symlinks; tools that rewrite worktree metadata.","solutions":["Inspect the path in the error with `ls -la`; if it is a symlink, replace it with a real directory or recreate the worktree","Run `git worktree list` and `git worktree prune`, then re-add the worktree with `git worktree add`","If the gitdir was replaced by a file, remove and re-create the worktree cleanly instead of editing internals"],"exampleFix":"// before: manual symlinked gitdir\nln -s /elsewhere/wt.git /repo/.git/worktrees/mywt\n// after: let git manage it\ngit worktree remove --force mywt && git worktree add ../mywt -b mybranch","handlingStrategy":"validation","validationCode":"info, err := os.Lstat(gitDir)\nif err != nil || info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {\n    return fmt.Errorf(\"refusing: gitdir %s is not a real directory\", gitDir)\n}","typeGuard":"func isRealDir(path string) bool {\n    info, err := os.Lstat(path)\n    return err == nil && info.Mode()&os.ModeSymlink == 0 && info.IsDir()\n}","tryCatchPattern":null,"preventionTips":["Never hand-edit .git/worktrees/<name>/ metadata; use git worktree add/remove/repair","Check `git worktree list` before scripted removals","Avoid symlinking worktree gitdirs across filesystems"],"tags":["git","worktree","filesystem"],"backgroundTag":"worktree-gitdir-not-a-directory","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}