coleam00/Archon · warning

Unexpected error deleting branch '${branchName}': ${err.mess

Error message

Unexpected error deleting branch '${branchName}': ${err.message}

What it means

In deleteBranchTracked, WorktreeProvider attempts `git branch -d` and classifies failures. 'Already gone' is success and 'checked out at' is a structured warning, but any other git failure is recorded as an 'Unexpected error deleting branch' warning and the deletion is reported as failed (return false). It is a soft failure: the branch survives and the warning is pushed onto result.warnings.

Source

Thrown at packages/isolation/src/providers/worktree.ts:405

    try {
      await execFileAsync('git', ['-C', repoPath, 'branch', '-D', branchName], {
        timeout: GIT_OPERATION_TIMEOUT_MS,
      });
      getLog().debug({ repoPath, branchName }, 'branch_deleted');
      return true;
    } catch (error) {
      const err = error as Error & { stderr?: string };
      const errorText = `${err.message} ${err.stderr ?? ''}`;

      if (errorText.includes('not found') || errorText.includes('did not match any')) {
        getLog().debug({ repoPath, branchName }, 'branch_already_deleted');
        return true; // Already gone counts as success
      } else if (errorText.includes('checked out at')) {
        const warning = `Cannot delete branch '${branchName}': branch is checked out elsewhere`;
        getLog().warn({ repoPath, branchName }, 'branch_checked_out_elsewhere');
        result.warnings.push(warning);
        return false;
      } else {
        const warning = `Unexpected error deleting branch '${branchName}': ${err.message}`;
        getLog().error({ err: error, repoPath, branchName }, 'branch_delete_failed');
        result.warnings.push(warning);
        return false;
      }
    }
  }

  /**
   * Delete a remote branch and track the result. Never throws - remote branch deletion is best-effort.
   * Returns true if branch was deleted or already gone, false if deletion failed.
   */
  private async deleteRemoteBranchTracked(
    repoPath: string,
    branchName: string,
    result: DestroyResult,
    remote = 'origin'
  ): Promise<boolean> {

View on GitHub (pinned to 0773b97458)

Solutions

  1. Inspect the logged branch_delete_failed entry for the underlying git error.
  2. Run `git branch -d <branch>` manually; if unmerged, merge it first or delete with `git branch -D <branch>` if you are sure.
  3. Retry destroy() once the conflicting git operation (gc, another checkout) finishes.
  4. If the branch must always be force-deleted on teardown, adjust the provider call to use `-D`.

Example fix

// before
result.warnings.push(`Unexpected error deleting branch '${branchName}': ${err.message}`);
// after
// force-delete an unmerged branch after confirming it is safe
await exec(`git -C ${repoPath} branch -D ${branchName}`);
Defensive patterns

Strategy: try-catch

Validate before calling

const merged = await git(['branch', '--no-merged', 'HEAD'], repoPath);
const willRefuse = merged.includes(branchName);
if (willRefuse) console.warn(`branch ${branchName} has unmerged commits; -d will fail`);

Try / catch

const ok = await provider.destroy(worktree);
for (const w of result.warnings) {
  if (w.startsWith('Unexpected error deleting branch')) {
    // inspect logs, decide on force delete
  }
}

Prevention

When it happens

Trigger: Calling destroy() on a worktree whose tracked branch cannot be deleted because git rejects it for a reason other than 'already gone' or 'checked out at' — e.g. the branch is not fully merged and `-d` refuses without `-D`, or the ref is corrupted/locked.

Common situations: Deleting a worktree whose branch has unmerged commits (git refuses `branch -d`); a packed-refs permission problem; concurrent gc/repack locking the ref during teardown.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/b369fcd2499d1628. Report an issue: GitHub.