{"record":{"id":"001d9db33e5be938","repo":"gastownhall/beads","slug":"failed-to-inspect-target-cleanliness-w","errorCode":null,"errorMessage":"failed to inspect target cleanliness: %w","messagePattern":"failed to inspect target cleanliness: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/worktree_cmd.go","lineNumber":993,"sourceCode":"\t\t\"--quiet\",\n\t\t\"--end-of-options\",\n\t\t\"HEAD^{commit}\",\n\t)\n\tif err != nil {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"target HEAD does not resolve to a commit: %w\", err)\n\t}\n\tstatusOutput, err := git.output(\n\t\tctx,\n\t\tworktree.path,\n\t\t\"status\",\n\t\t\"--porcelain=v1\",\n\t\t\"-z\",\n\t\t\"--untracked-files=all\",\n\t\t\"--ignore-submodules=none\",\n\t\t\"--ignored=matching\",\n\t)\n\tif err != nil {\n\t\treturn pinnedWorktreeTarget{}, fmt.Errorf(\"failed to inspect target cleanliness: %w\", err)\n\t}\n\n\theadOID := strings.TrimSpace(string(headOutput))\n\tif headOID == \"\" || headOID != worktree.headOID {\n\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)","sourceCodeStart":975,"sourceCodeEnd":1011,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/worktree_cmd.go#L975-L1011","documentation":"inspectWorktreeTarget runs `git status --porcelain=v1 -z --untracked-files=all --ignore-submodules=none --ignored=matching` to snapshot the worktree's cleanliness before removal. If git status itself fails, this wrapped error is returned. bd requires a reliable status fingerprint before removing a worktree.","triggerScenarios":"`git status` failing inside the target worktree due to a broken or locked index (index.lock present), unreadable working tree, submodule errors, or a canceled/timed-out git subprocess during removal or revalidation.","commonSituations":"A concurrent git process crashed leaving index.lock; permissions changed on the worktree; a broken submodule blocks status; the filesystem is unavailable (unmounted network volume).","solutions":["Run `git -C <path> status` manually to see the underlying error and fix it (e.g. remove a stale index.lock — only when no git process is running).","Fix permissions on the worktree directory so the current user can read it.","Deinit or repair the offending submodule if it blocks status.","Retry after resolving; if the worktree is disposable, prune via `git worktree prune` and clear the registry."],"exampleFix":"// before\nbd worktree remove feature-x\n// error: failed to inspect target cleanliness: ... index.lock exists\n// after\ngit -C /repo/.worktrees/featurex status   # confirm no live git process, then:\nrm -f /repo/.git/worktrees/feature-x/index.lock\nbd worktree remove feature-x","handlingStrategy":"try-catch","validationCode":"const st = Bun.spawnSync([\"git\", \"-C\", worktreePath, \"status\", \"--porcelain\"]);\nif (st.exitCode !== 0) throw new Error(\"git status fails: \" + st.stderr.toString());","typeGuard":null,"tryCatchPattern":"try {\n  await bd(\"worktree\", \"remove\", path);\n} catch (e) {\n  if (String(e.message).includes(\"failed to inspect target cleanliness\")) {\n    // only if no git process is running:\n    execSync(`rm -f /repo/.git/worktrees/${name}/index.lock`);\n    // then retry\n  } else throw e;\n}","preventionTips":["Don't run concurrent git/bd operations on the same worktree.","Clean up crashed git processes and stale index.lock files.","Keep submodules healthy (`git submodule status`).","Ensure the worktree filesystem is mounted and readable."],"tags":["worktree","git","status","index-lock"],"backgroundTag":"git-index-locked","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}