gastownhall/beads · error

failed to inspect created worktree cleanliness: %w %s

Error message

failed to inspect created worktree cleanliness: %w
%s

What it means

After `bd worktree create` checks out a new worktree, ensureCreatedWorktreeClean runs `git status --porcelain=v1 --untracked-files=all` inside it to verify the checkout succeeded. If the git subprocess itself exits non-zero (rather than reporting a dirty status), this error wraps the exec error plus the combined stdout/stderr of git. It is a safety gate: bd refuses to continue without confidence the new worktree is clean.

Source

Thrown at cmd/bd/worktree_cmd.go:451

	fmt.Printf("  Main repo: %s\n", mainRepoRoot)
	if redirectInfo.IsRedirected {
		fmt.Printf("  Beads: redirects to %s\n", redirectInfo.TargetDir)
	} else {
		fmt.Printf("  Beads: local (no redirect)\n")
	}

	return nil
}

// Helper functions

var checkCreatedWorktreeClean = ensureCreatedWorktreeClean

func ensureCreatedWorktreeClean(ctx context.Context, worktreePath string) error {
	gitCmd := gitCmdInDir(ctx, worktreePath, "status", "--porcelain=v1", "--untracked-files=all")
	output, err := gitCmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to inspect created worktree cleanliness: %w\n%s", err, string(output))
	}

	if status := strings.TrimSpace(string(output)); status != "" {
		return fmt.Errorf("created worktree is dirty after checkout; refusing to continue: %s\n%s", worktreePath, status)
	}

	return nil
}

// gitCmdInDir creates a git command that runs in the specified directory.
// This is used for worktree operations that need to run in a specific location
// (either the CWD repo root or a specific worktree path).
//
// Security: Sets core.hooksPath and GIT_TEMPLATE_DIR to disable hooks/templates
// for defense-in-depth, matching the pattern in RepoContext.GitCmd().
func gitCmdInDir(ctx context.Context, dir string, args ...string) *exec.Cmd {
	gitArgs := append([]string{"-c", "core.hooksPath="}, args...)
	cmd := exec.CommandContext(ctx, "git", gitArgs...)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the appended git output in the error message to see the actual git failure cause
  2. Run `git status --porcelain=v1` manually inside the worktree path to reproduce
  3. Fix the underlying git issue (e.g. git-lfs: run `git lfs install`; locks: remove index.lock)
  4. Remove the bad worktree and re-create it: `git worktree remove <path> --force` then `bd worktree create ...`

Example fix

// reproduce/diagnose
cd /path/to/new-worktree && git status --porcelain=v1
// if git-lfs filter fails
git lfs install && git worktree remove --force . && bd worktree create .
Defensive patterns

Strategy: try-catch

Validate before calling

cd <worktreePath> && git status --porcelain=v1 --untracked-files=all
# expect exit 0 and empty output before/after bd worktree create

Try / catch

out, err := exec.Command("git", "-C", wtPath, "status", "--porcelain=v1").CombinedOutput()
if err != nil {
    return fmt.Errorf("git status failed in %s: %w\n%s", wtPath, err, out)
}

Prevention

When it happens

Trigger: `git status` returning non-zero in the freshly created worktree path — e.g. the worktree directory is corrupt, .git metadata missing, a git hook (hooks are suppressed but config aliases/smudge filters can still fail), or the checkout left git in a bad state.

Common situations: Broken git configuration (e.g. a global filter driver like git-lfs that fails on checkout); antivirus/index locks interfering on Windows; disk full during checkout; worktree path created but registration with the main repo failed.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/d5c1bb2fd28ef2ac. Report an issue: GitHub.