Bash CWD becomes permanently invalid after subagent completion -- session unrecoverable

Resolved 💬 3 comments Opened Apr 9, 2026 by RamXX Closed Apr 13, 2026

Summary

After a subagent (spawned via the Agent tool, without isolation: "worktree") completes, the parent session's Bash CWD sometimes changes to the subagent's final CWD. If that directory is later removed, every subsequent Bash command fails permanently with Error: Path "..." does not exist. The session cannot recover; not even cd /absolute/path works.

Context

We build Paivot, a multi-agent software delivery methodology implemented as a Claude Code plugin. It uses a dispatcher pattern where an orchestrator spawns ephemeral developer agents that work inside manually-created git worktrees (.claude/worktrees/dev-*). Developer agents are spawned as regular Agent calls (no isolation parameter) because isolation: "worktree" creates a worktree-agent-* branch that is disconnected from the story branch.

The dispatcher creates the worktree manually, the developer agent cd's into it, works, and delivers. When the developer completes, the dispatcher removes the worktree. This workflow has worked for hundreds of story deliveries, but intermittently, after the developer completes, the dispatcher's Bash CWD has silently changed to the worktree path. Once the worktree is removed, the session is permanently dead.

Reproduction

  1. In a git repo, create a worktree: git worktree add .claude/worktrees/dev-test main
  2. Spawn a subagent (Agent tool, NO isolation parameter) with a prompt that has it cd .claude/worktrees/dev-test and run several Bash commands there
  3. Let the agent complete normally
  4. In the parent session, run any Bash command (e.g., pwd)

Expected: Parent session's Bash CWD is unchanged (still the project root where it was before the Agent call).

Actual: Parent session's Bash CWD has changed to the subagent's final CWD. If you then remove the worktree (git worktree remove .claude/worktrees/dev-test), every subsequent command fails:

Error: Path "/path/to/repo/.claude/worktrees/dev-test" does not exist

Why it's unrecoverable

The Bash tool validates that CWD exists before executing any command, including cd /absolute/path. When the CWD path has been deleted:

  • No Bash command can execute (validation rejects before the shell sees it)
  • PreToolUse hooks may also fail to start (OS returns ENOENT when spawning a process from a deleted CWD)
  • Spawning a new sub-agent works (agents get fresh CWD), but cannot fix the parent's Bash CWD
  • The only recovery is restarting Claude Code

Suggested fix

When the Bash tool's tracked CWD doesn't exist, fall back to the project root instead of failing:

if !exists(cwd) { cwd = projectRoot }

This would make the session self-healing. The CWD leakage from subagent to parent is the deeper bug, but the fallback alone would eliminate the unrecoverable state.

Workarounds we've implemented

We've added three defense layers in our plugin (pvg), none of which fully prevent the issue:

  1. SubagentStop hook cleanup: when a developer agent completes, the hook proactively removes dev worktrees using git -C root (CWD-independent), reducing the window for corruption
  2. Developer agent CWD reset: agents are instructed to run cd $PROJECT_ROOT as their last Bash command before completing, so the leaked CWD is at least a valid path
  3. CWD drift guard: a PreToolUse hook that detects when CWD is inside a worktree with no active agent and blocks with a recovery instruction, but this only fires if the CWD path still exists

Workaround #2 is the most effective but depends on the subagent remembering to follow prompt instructions.

Environment

  • Claude Code CLI (macOS, darwin arm64)
  • Model: claude-opus-4-6 (but the bug is in the harness, not the model)
  • Observed across multiple projects over several weeks

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗