ExitPlanMode resets Write tool's Read-tracking state, causing file update failures and duplicate side effects

Resolved 💬 1 comment Opened Apr 14, 2026 by BikiBikiBik Closed May 25, 2026

Summary

After ExitPlanMode, the Write tool loses track of files it has already created or read in the same session. This causes the Write tool to reject updates to files the AI just created seconds ago, leading to a cascade of failures and duplicate irreversible side effects (e.g., duplicate emails).

Environment

  • Claude Code version: Latest (2026-04-14)
  • Model: claude-opus-4-6
  • OS: Windows 11 Pro
  • Shell: bash (via Claude Code)

Steps to Reproduce

  1. Start a session that uses plan mode (e.g., a skill with EnterPlanMode → auto-approve → ExitPlanMode)
  2. After ExitPlanMode, create a new file using Writesucceeds
  3. Modify the file externally via Bash (e.g., add UTF-8 BOM with PowerShell)
  4. Attempt to update the same file using Writefails with "File has not been read yet"
  5. The AI then executes subsequent steps (e.g., sending an email via Bash) that succeed because Bash is unaffected
  6. The AI eventually recovers by reading an arbitrary file ("Read priming"), then recreates the file and re-executes all steps — including the irreversible email send

Observed Behavior

Two distinct Write errors occur in a death spiral:

Error 1: "File has not been read yet"

After ExitPlanMode, a file the AI just created in the same session is treated as "never read." The Write tool rejects overwrite attempts even though the AI created the file moments ago.

Error 2: "File has been modified since read"

When the AI uses Bash to modify a file (e.g., adding BOM encoding), the Write tool detects the external change and rejects further writes. This is expected but compounds with Error 1.

Combined effect:

  • The AI cannot update its own files after ExitPlanMode + external modification
  • Bash-based side effects (email, API calls) continue working since they bypass Write's guards
  • This creates a partial execution state: irreversible actions complete while file operations fail
  • The AI enters a recovery loop (tries Write → fails → tries cat > heredoc → fails → tries Python script → fails → eventually discovers Read priming)
  • Upon recovery, the AI re-executes the entire workflow including the already-sent email, causing a duplicate

Evidence from Session JSONL

L108: ExitPlanMode
L133: Write(prompt.md) → SUCCESS (file created)
L149: Bash(PowerShell BOM addition) → SUCCESS (external file modification)
L151: Write(prompt.md) → FAIL "File has not been read yet"
L154: Bash(send-email.ps1) → "SENT OK" ← 1st email
L211: Write(prompt.md) → FAIL (same error, now during /end skill)
L237: Write(prompt.md) → FAIL (3rd attempt)
L241: Bash(heredoc cat >) → FAIL (EOF parsing)
L263: Bash(python3 write) → FAIL (script not found)
L265: Read(unrelated_file.md) → SUCCESS ← "Read priming" unlocks Write
L280: Write(prompt.md) → SUCCESS (file recreated)
L291: Bash(send-email.ps1) → "SENT OK" ← 2nd email (DUPLICATE)

File system evidence: prompt.md CreationTime = 20:31 (not 20:16 when first created), confirming the file was deleted and recreated during recovery.

Expected Behavior

  1. After ExitPlanMode, the Write tool should retain knowledge of files created/read in the same session
  2. A file the AI just created via Write should be updatable without requiring a separate Read call
  3. At minimum: if Write fails, the error message should suggest "Read the file first" rather than leaving the AI to discover the workaround through trial and error

Impact

  • Duplicate irreversible side effects: Emails, API calls, or other Bash-based actions get executed twice
  • False checkpoint records: The AI creates a checkpoint claiming files were written (because they were — initially), but then can't update them
  • Wasted compute: 80+ lines of recovery attempts (Write → heredoc → Python → Read priming) before succeeding
  • User confusion: User receives duplicate communications and must investigate which session caused it

Suggested Fix

Option A (preferred): ExitPlanMode should preserve the Write tool's file-tracking state from the plan phase
Option B: Write tool should implicitly track files it has written as "known" (no Read required before re-write)
Option C: Write tool should accept re-writes to files created in the same session, regardless of Read state

View original on GitHub ↗

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