gastownhall/beads · error

cannot remove a worktree when the primary worktree is bare

Error message

cannot remove a worktree when the primary worktree is bare

What it means

bd refuses to remove a worktree when the primary (first registered) worktree is a bare repository. In a bare primary setup, worktree bookkeeping and the .gitignore/paths bd manages differ enough that the removal plan would be unsafe, so bd fails fast with this explicit error. It is thrown from the removal-plan builder (cmd/bd/worktree_cmd.go:1236).

Source

Thrown at cmd/bd/worktree_cmd.go:1236

		return nil, err
	}
	currentDirectory, err := os.Getwd()
	if err != nil {
		return nil, fmt.Errorf("failed to resolve current directory: %w", err)
	}
	currentRootOutput, err := gitRunner.output(ctx, currentDirectory, "rev-parse", "--show-toplevel")
	if err != nil {
		return nil, fmt.Errorf("not in a git worktree: %w", err)
	}
	currentRoot := filepath.Clean(strings.TrimSpace(string(currentRootOutput)))

	worktrees, err := listRegisteredWorktrees(ctx, gitRunner, currentRoot)
	if err != nil {
		return nil, err
	}
	mainWorktree := worktrees[0]
	if mainWorktree.bare {
		return nil, fmt.Errorf("cannot remove a worktree when the primary worktree is bare")
	}
	targetEntry, err := resolveRegisteredWorktree(name, currentRoot, mainWorktree.path, worktrees)
	if err != nil {
		return nil, err
	}
	plan := &worktreeRemovalPlan{
		force: options.force.value,
		prepareFacts: worktreeremove.PrepareFacts{
			Registration: worktreeremove.Present,
		},
	}
	if targetEntry.isMain {
		plan.prepareFacts.Target = worktreeremove.PrimaryWorktree
		return plan, nil
	}
	if sameWorktreePath(targetEntry.path, currentRoot) {
		plan.prepareFacts.Target = worktreeremove.CurrentWorktree
		return plan, nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run the removal from / target a non-bare setup: create a normal primary worktree with `git worktree add <path> <branch>` (or re-clone non-bare) and remove the worktree there
  2. Remove the worktree manually with `git worktree remove <path>` if bd's managed cleanup (.gitignore entries) is not needed
  3. Restructure the repo so the bare directory is not the primary worktree (clone non-bare, add the bare as secondary or drop it)

Example fix

// before
$ git init --bare /srv/repo.git && git worktree add /srv/main
$ bd worktree remove /srv/main
// error: cannot remove a worktree when the primary worktree is bare
// after: use a non-bare primary
$ git clone /srv/repo.git /srv/repo && cd /srv/repo && git worktree remove ../main
Defensive patterns

Strategy: validation

Validate before calling

first=$(git worktree list --porcelain | awk '/^worktree /{print $2; exit}')
if git -C "$first" rev-parse --is-bare-repository | grep -q true; then echo 'primary worktree is bare'; exit 1; fi

Type guard

func primaryWorktreeIsBare(entries []worktreeEntry) bool {
	return len(entries) > 0 && entries[0].bare
}

Try / catch

plan, err := buildWorktreeRemovalPlan(ctx, git, name, nil)
if err != nil && strings.Contains(err.Error(), "primary worktree is bare") {
	return fmt.Errorf("use `git worktree remove` directly, or set up a non-bare primary worktree")
}

Prevention

When it happens

Trigger: Invoking `bd worktree remove <name>` while the repository's primary worktree (worktrees[0] from `git worktree list`) has the `bare` flag, e.g. a repo created with `git init --bare` or `git clone --bare` with linked worktrees attached.

Common situations: Server-style bare repos with linked checkouts; CI setups cloning with --bare then adding worktrees; repos restructured so the bare dir became the primary worktree.

Related errors


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