{"record":{"id":"7a8795df41bc9baf","repo":"gastownhall/beads","slug":"created-worktree-is-dirty-after-checkout-refusing","errorCode":null,"errorMessage":"created worktree is dirty after checkout; refusing to continue: %s\n%s","messagePattern":"created worktree is dirty after checkout; refusing to continue: (.+?)\n(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/worktree_cmd.go","lineNumber":455,"sourceCode":"\t\tfmt.Printf(\"  Beads: local (no redirect)\\n\")\n\t}\n\n\treturn nil\n}\n\n// Helper functions\n\nvar checkCreatedWorktreeClean = ensureCreatedWorktreeClean\n\nfunc ensureCreatedWorktreeClean(ctx context.Context, worktreePath string) error {\n\tgitCmd := gitCmdInDir(ctx, worktreePath, \"status\", \"--porcelain=v1\", \"--untracked-files=all\")\n\toutput, err := gitCmd.CombinedOutput()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to inspect created worktree cleanliness: %w\\n%s\", err, string(output))\n\t}\n\n\tif status := strings.TrimSpace(string(output)); status != \"\" {\n\t\treturn fmt.Errorf(\"created worktree is dirty after checkout; refusing to continue: %s\\n%s\", worktreePath, status)\n\t}\n\n\treturn nil\n}\n\n// gitCmdInDir creates a git command that runs in the specified directory.\n// This is used for worktree operations that need to run in a specific location\n// (either the CWD repo root or a specific worktree path).\n//\n// Security: Sets core.hooksPath and GIT_TEMPLATE_DIR to disable hooks/templates\n// for defense-in-depth, matching the pattern in RepoContext.GitCmd().\nfunc gitCmdInDir(ctx context.Context, dir string, args ...string) *exec.Cmd {\n\tgitArgs := append([]string{\"-c\", \"core.hooksPath=\"}, args...)\n\tcmd := exec.CommandContext(ctx, \"git\", gitArgs...)\n\tcmd.Dir = dir\n\t// Security: Disable git hooks and templates (SEC-001, SEC-002)\n\tcmd.Env = append(os.Environ(),\n\t\t\"GIT_TEMPLATE_DIR=\",","sourceCodeStart":437,"sourceCodeEnd":473,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/worktree_cmd.go#L437-L473","documentation":"After creating a worktree, bd runs `git status --porcelain` and refuses to continue if the output is non-empty — the freshly checked-out worktree must be clean. This is an integrity check: a dirty new worktree means something (a hook, filter, or stale files) modified or added files during/right after checkout.","triggerScenarios":"`bd worktree create` produces a worktree whose `git status --porcelain=v1 --untracked-files=all` lists modified or untracked files immediately after checkout — e.g. smudge filters writing files, pre-existing files colliding with checked-out paths, or generated files appearing from build hooks.","commonSituations":"A target branch's checkout triggers git-lfs smudging that fails partway; .gitignore missing so build artifacts inside the worktree path show as untracked; a previous worktree at the same path left files behind that git checkout did not overwrite.","solutions":["Inspect the status list in the error message to see which files are dirty","Remove the worktree and retry with a clean path: `git worktree remove <path> --force`","Add appropriate .gitignore entries so generated/untracked files don't appear","Check for smudge filters or hooks modifying files at checkout (git config filter.*, core.hooksPath)"],"exampleFix":"// before\nbd worktree create ../wt-feature -b feature   # fails: untracked build.log\n// after\necho build.log >> .gitignore\ngit worktree remove ../wt-feature --force\nbd worktree create ../wt-feature -b feature","handlingStrategy":"validation","validationCode":"status=$(git -C \"$WT_PATH\" status --porcelain=v1 --untracked-files=all)\nif [ -n \"$status\" ]; then echo \"worktree dirty: $status\"; exit 1; fi","typeGuard":null,"tryCatchPattern":"if status := strings.TrimSpace(string(output)); status != \"\" {\n    // clean the worktree or fix the filter/hook that dirtied it before retrying\n    return fmt.Errorf(\"worktree %s dirty: %s\", wtPath, status)\n}","preventionTips":["Commit .gitignore entries for build artifacts before creating worktrees","Disable or verify smudge filters/hooks that write at checkout","Use fresh, non-previously-used worktree paths","Run `git worktree remove --force` on failed creates before retrying"],"tags":["go","git","worktree","dirty-checkout"],"backgroundTag":"dirty-worktree-after-checkout","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}