Parallel agents with isolation: "worktree" fail due to git config lock race condition

Resolved 💬 1 comment Opened Apr 13, 2026 by paulporsche Closed May 25, 2026

Bug Description

When launching multiple agents with isolation: "worktree" in a single message (parallel execution), 2 out of 3 agents fail with:

error: could not lock config file .git/config: File exists
error: unable to write upstream branch configuration

This happens because each agent invokes git worktree add simultaneously, and git uses file locking (.git/config.lock) to serialize writes. Under concurrent load, these locks collide.

Reproduction Steps

  1. In any git repository, launch 3 agents in parallel with worktree isolation in a single message:
Agent(description="task 1", isolation="worktree", prompt="...")
Agent(description="task 2", isolation="worktree", prompt="...")
Agent(description="task 3", isolation="worktree", prompt="...")
  1. Typically 1 agent succeeds and the other 2 fail with the config lock error.

Expected Behavior

All 3 agents should successfully create their worktrees. Claude Code should either:

  • Serialize worktree creation internally before dispatching agents in parallel
  • Add retry logic with backoff to git worktree add calls
  • Use a mutex/lock around worktree creation

Current Workaround

A WorktreeCreate hook with retry + exponential backoff:

#!/bin/bash
set -euo pipefail
input=$(cat)
base_path=$(echo "$input" | python3 -c "import sys,json; print(json.load(sys.stdin).get('base_path',''))")
branch=$(echo "$input" | python3 -c "import sys,json; print(json.load(sys.stdin).get('branch',''))")
isolation_id=$(echo "$input" | python3 -c "import sys,json; print(json.load(sys.stdin).get('isolation_id',''))")
worktree_path="${base_path}/.claude/worktrees/${isolation_id:-$branch}"
max_retries=5
delay=1
for i in $(seq 1 $max_retries); do
    if git -C "$base_path" worktree add "$worktree_path" -b "$branch" 2>/dev/null; then
        echo "$worktree_path"
        exit 0
    fi
    if [ "$i" -lt "$max_retries" ]; then
        sleep "$delay"
        delay=$((delay * 2))
    fi
done
echo "Failed to create worktree after $max_retries retries" >&2
exit 1

Environment

  • macOS (Darwin 25.4.0)
  • Claude Code CLI
  • Git 2.x

Notes

This seems like it should be handled internally — the Agent tool explicitly supports both isolation: "worktree" and parallel agent launches in a single message, so the race condition is a natural consequence of using both features together.

🤖 Generated with Claude Code

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗