[BUG] Subagent's startup git status reports the parent session's cached branch, not its own working directory's
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
A subagent does not get a git status snapshot of its own working directory. Its Current branch: line
carries the parent session's cached branch instead. When the parent session has moved into a different git
worktree before spawning, the subagent works in one branch while its context names another. Agents then
report the wrong "active branch", and an agent told it is on the default branch can act on that (for
example by following "if on the default branch, branch first").
In the reproduction, the subagent's working directory is the beta worktree, but its context saysCurrent branch: alpha. The subagent's own transcript confirms this is its session_context attachment,
not text quoted from the brief.
What Should Happen?
The subagent's snapshot should describe the directory it starts in: Current branch: beta for a subagent
whose primary working directory is the beta worktree.
Error Messages/Logs
No error is raised. Output of the reproduction (temp path replaced with `<tmp>`):
beta
Current branch: alpha
- Primary working directory: <tmp>/repo-beta
The first line is `git branch --show-current` in the parent after `cd`. The next two are quoted by the
subagent from its own context.
Steps to Reproduce
Run this script. It creates a throwaway repo on branch alpha with a second worktree on branch beta,
starts a session in alpha, moves the shell into beta, and spawns a subagent. User settings are excluded
with --setting-sources project,local, so no user hooks or settings are involved.
#!/usr/bin/env bash
set -euo pipefail
root=$(mktemp -d)
git init -q -b alpha "$root/repo"
git -C "$root/repo" -c commit.gpgsign=false commit -q --allow-empty -m init
git -C "$root/repo" worktree add -q -b beta "$root/repo-beta"
cd "$root/repo"
claude -p "Step 1: run the Bash command 'cd $root/repo-beta' on its own. Step 2: run the Bash command 'git branch --show-current' on its own. Step 3: use the Agent tool to spawn one general-purpose subagent with this prompt: 'Do not use any tools. Quote verbatim the line beginning Current branch: from the git status in your context, and the line naming your primary working directory.' Then output three lines: the output of step 2, and the subagent's two quoted lines, verbatim." \
--setting-sources project,local --add-dir "$root/repo-beta" --allowedTools "Bash(cd:*)" "Bash(git branch:*)" "Agent"
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.280
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Non-interactive/CI environment
Additional Information
- First noticed in interactive sessions in the VS Code extension; the reproduction uses
claude -p. - Not a duplicate of #49169 or #81361. Those concern
isolation: "worktree"checkouts built from a stale
baseline, so the subagent reads old files. Here no isolation is used: the subagent runs in the correct
directory with the correct files, and git branch --show-current there returns the right branch. Only
the Current branch: line in its startup context is wrong.
- The value a subagent receives appears to be a branch the parent session caches and refreshes at
unpredictable moments. It did not refresh at each user prompt or at each cd; in one session it stayed
unchanged across three user prompts and 31 working-directory changes. When it does refresh, it takes the
branch of wherever the parent's shell is at that moment, so it can name a sibling worktree's branch.
- Across 46 real subagent runs in one project that recorded a snapshot, 45 received exactly the parent's
cached branch at spawn. The one exception was spawned about 44 ms before that cached value changed.
- Related, possibly a separate issue: a session started in a directory whose
.gitfile points at a bare
repository reports that bare repo's HEAD as Current branch: (including a branch that no longer
exists), and reports Status: (clean) even though git status fails there with fatal: this operation.
must be run in a work tree
- Workaround: a
SubagentStarthook that runsgit -C "$cwd" branch --show-currenton the hook input's
cwd and returns the result as hookSpecificOutput.additionalContext gives the subagent its real branch.
- Suggested fix: compute each subagent's git status snapshot from the subagent's own working directory at
spawn, or leave the branch out of subagent context rather than passing on the parent's cached value.