[BUG] Bash tool crashes with EEXIST when session-env folder already exists (mkdir missing recursive: true)
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?
The Claude Code Bash tool crashes intermittently mid-session with the following error:
EEXIST: file already exists, mkdir 'C:\Users\<user>\.claude\session-env\<session-id>'
The <session-id> in the error message matches the current session's ID — meaning the host process is calling mkdir on a folder it already created earlier in the same session, without { recursive: true } and without an existence check.
This is the same bug class that previously crashed Stop hooks (forced disable of the ralph-loop plugin) and PreToolUse:Edit/Write hooks (forced disable of the security-guidance plugin) in this environment over the last 36 hours. A single shared code path in the host appears to call bare mkdirSync(path) on the session-env folder without idempotency, and Bash tool execution + hook execution both go through it.
In one 14-hour session on 2026-05-08 (vanilla HTML prototype build, no npm/node steps), the bug fired 8-10 separate times during routine Bash calls (git log, grep, wc, curl, magick). It blocked image-cropping work entirely; manual fallback to external tooling was required.
A side effect of the bug: ~/.claude/session-env/ accumulates orphaned per-session folders indefinitely — 258 folders dating back to 2026-04-10 in this environment, almost all empty. There is no apparent cleanup on session end.
What Should Happen?
The Bash tool should be able to invoke commands repeatedly within a single session without crashing on its own session-env folder.
Specifically:
- Folder creation must be idempotent. Replace bare
mkdirSync(path)withmkdirSync(path, { recursive: true }), or guard withif (!existsSync(path)) mkdirSync(path). - The session's folder should be cleaned up on graceful shutdown, plus a startup sweep of folders older than e.g. 24 hours, to prevent indefinite accumulation in
~/.claude/session-env/.
Error Messages/Logs
EEXIST: file already exists, mkdir 'C:\Users\<user>\.claude\session-env\<session-id>'
Steps to Reproduce
- Start a Claude Code session on Windows 11 (PowerShell or Git Bash as host shell, hosted inside VS Code integrated terminal).
- Run several Bash tool calls in succession during the same session — anything routine works:
echo hello,git log --oneline -5,wc -l <file>,grep <pattern> <file>. - After several Bash calls within the same session (frequency varies; observed 8-10 times in a 14-hour session), a subsequent Bash call returns:
EEXIST: file already exists, mkdir 'C:\Users\<user>\.claude\session-env\<session-id>'
The <session-id> in the error matches the current session's ID — i.e. the host is mkdir-ing a folder it created earlier in the same session.
- Recovery (workaround): from PowerShell (outside the dead Bash tool), run:
Remove-Item 'C:\Users\<user>\.claude\session-env\<session-id>' -Recurse -Force
The next Bash tool call succeeds. The bug recurs after a few more calls.
The bug fires for routine commands; no special syntax, environment variables, or filesystem operations are required to trigger it. It is non-deterministic in timing within a session but reliably recurrent across long sessions.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.138 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
VS Code integrated terminal
Additional Information
Related incidents in the same environment (cross-surface evidence)
The same EEXIST mkdir 'session-env\<id>' symptom has appeared on three Claude Code surfaces in this user's environment over ~36 hours:
| Date | Surface | User-visible action |
|---|---|---|
| 2026-05-08 | Stop hooks (ralph-loop plugin) | Plugin uninstalled |
| 2026-05-09 | PreToolUse:Edit/Write hooks (security-guidance plugin) | Plugin disabled |
| 2026-05-08 → 2026-05-09 | Bash tool itself | No fix available, manual recovery only |
This strongly suggests a single shared code path used by Bash tool execution and hook execution — a fix in one place likely resolves all three surfaces.
Environment details
- Windows 11 Pro 10.0.26200
- PowerShell 5.1 (host shell)
- Git Bash (MSYS2) at
/usr/bin/bash5.2.37 (Bash tool runtime) - Node.js v24.14.0
- Settings:
defaultShell: powershell,CLAUDE_CODE_USE_POWERSHELL_TOOL=1(PowerShell tool path is unaffected by this bug — used as the recovery channel)
Side effect: directory leak
~/.claude/session-env/ accumulated 258 orphaned per-session folders dating back to 2026-04-10 before manual cleanup. No graceful or startup cleanup observed.
Suggested fix (one line)
Replacefs.mkdirSync(sessionEnvPath);
Withfs.mkdirSync(sessionEnvPath, { recursive: true });
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗