Skip to content

Bug: isolation: 'worktree' renames worker branches and leaves the primary worktree checked out on a run branch #79748

Description

@ppinault

Repo to file against: anthropics/claude-code
Labels (suggested): bug, sdk, workflow, git-worktree


Summary

When spawning agents with isolation: 'worktree' (via the Workflow tool / Agent
SDK), two git-state invariants are broken:

  1. Branch renaming. Workers are asked to create and work on a branch named
    run/<runId>/<id>-<slug> (passed in the task brief). Instead, the harness
    materializes branches named worktree-<workflowId>-<N>. The requested branch
    name is not honored.
  2. Primary worktree left on a run branch. After the isolated agents finish,
    the primary worktree (repo root) is sometimes left checked out on a
    run/* / worktree-* branch instead of the base branch it started on.

Observed on 5 consecutive orchestration runs (5/5).

Impact

  • Downstream tooling that keys off the branch naming convention
    (run/<runId>/...) silently fails to match — guardrails that should fire on
    run/* don't, because the actual branches are worktree-*. This is a silent
    hole, not a loud failure.
  • The primary worktree ending up on a worker branch requires a defensive
    "reconquer the main worktree" step (checkout base) before any journal write,
    or subsequent operations run against the wrong branch.
  • An audit-only task declared with branch: null (report only, no code)
    still materializes an empty branch + leftover worktree-* artifacts that must
    be pruned.

Steps to reproduce

  1. Run a Workflow that spawns ≥2 agents with isolation: 'worktree', each brief
    instructing the agent to git checkout -b run/<runId>/<id>-<slug> from a
    captured base SHA.
  2. Let the agents complete and return.
  3. Inspect: git worktree list and git branch --list 'run/*' 'worktree-*'.

Expected

  • Worker branches are named exactly as instructed (run/<runId>/<id>-<slug>).
  • After the run, the primary worktree is back on the base branch it started on.
  • A task declared branch: null produces no branch/worktree artifact.

Actual

  • Branches are named worktree-<workflowId>-<N>.
  • The primary worktree is sometimes left on a run/* / worktree-* branch.
  • branch: null tasks still leave an empty branch + worktree-* vestiges.

Current workaround (in our command layer)

  • /run Phase 6.0 checks git -C <root> branch --show-current and, if it is not
    the expected base, runs git -C <root> checkout <base> before writing anything.
  • Prune step covers both run/* and worktree-* prefixes (fail-closed:
    only delete branches proven 0 commits ahead of origin/main).
  • These are mitigations, not fixes: the naming and primary-worktree behavior are
    in the harness and cannot be corrected from a command .md or a shell script.

Environment

  • Claude Code 2.1.216
  • macOS 26.5.2 (build 25F84)
  • Orchestration via the Workflow tool with isolation: 'worktree'

(This ticket is the residual non-software action tracked as ORCH-1 in our flow —
see FLOW-MAP.md → « Dette hors-commande ». Fill the version/OS blanks before
filing.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions