claude-code - 💡(How to fix) Fix [BUG] Bash tool and SessionStart hooks fail with EEXIST on Windows due to non-idempotent mkdir of session-env

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

Error Messages/Logs

SessionStart:resume hook ⎿ Failed to run: EEXIST: error file already exists, 3. Invoke any Bash tool call (e.g. ask Claude to run git status). The Bash call returns the EEXIST error

Root Cause

The hook actually succeeds — its env file (sessionstart-hook-1.sh) is written to the directory on the first attempt. But a subsequent mkdir of the same path errors out because the harness isn't using idempotent mkdir semantics (no recursive: true / no pre-check).

Fix Action

Fix / Workaround

Reproduces 100% on my machine across multiple sessions on multiple days. Workaround: use the PowerShell tool instead of Bash — it does not trigger the same setup code path.

Code Example

EEXIST: file already exists, mkdir 'C:\Users\<user>\.claude\session-env\<session-id>'

---

EEXIST: file already exists, mkdir 'C:\Users\PC\.claude\session-env\30ccd257-2836-4f6a-9578-002d6bf53ee2'


SessionStart:resume hook UI message:


SessionStart:resume hook    ⎿  Failed to run: EEXIST: error file already exists,
                                mkdir 'C:\Users\PC\.claude\session-env\b09856cb-f292-4edc-b209-b1c8133962d3'

---

%USERPROFILE%\.claude\session-env\<session-id>\sessionstart-hook-1.sh

---

(Get-ChildItem "$env:USERPROFILE\.claude\session-env" -Directory).Count

---

session-env/b09856cb-f292-4edc-b209-b1c8133962d3/
  sessionstart-hook-1.sh    153 bytes    (READ-ONLY directory attribute set)
  └─ contents:
       export CODEX_COMPANION_SESSION_ID='b09856cb-f292-4edc-b209-b1c8133962d3'
       export CLAUDE_PLUGIN_DATA='C:/Users/PC/.claude/plugins/data/codex-openai-codex'
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

On Windows, every Bash tool call and every SessionStart:resume hook invocation fails with:

EEXIST: file already exists, mkdir 'C:\Users\<user>\.claude\session-env\<session-id>'

The hook actually succeeds — its env file (sessionstart-hook-1.sh) is written to the directory on the first attempt. But a subsequent mkdir of the same path errors out because the harness isn't using idempotent mkdir semantics (no recursive: true / no pre-check).

What Should Happen?

mkdir session-env/<session-id>/ should be idempotent. Directory-already-exists is the normal steady state mid-session and should not raise EEXIST.

Bash tool calls should not fail because of an internal harness setup step. The SessionStart hook should not report "Failed to run" when it actually succeeded.

Error Messages/Logs

EEXIST: file already exists, mkdir 'C:\Users\PC\.claude\session-env\30ccd257-2836-4f6a-9578-002d6bf53ee2'


SessionStart:resume hook UI message:


SessionStart:resume hook    ⎿  Failed to run: EEXIST: error file already exists,
                                mkdir 'C:\Users\PC\.claude\session-env\b09856cb-f292-4edc-b209-b1c8133962d3'

Steps to Reproduce

  1. On Windows, install Claude Code and a plugin that registers a SessionStart hook (e.g. codex@openai-codex).
  2. Start a Claude Code session. The hook fires; observe the file is created:
    %USERPROFILE%\.claude\session-env\<session-id>\sessionstart-hook-1.sh
  3. Invoke any Bash tool call (e.g. ask Claude to run git status). The Bash call returns the EEXIST error immediately.
  4. Alternatively, trigger a session resume that re-fires the SessionStart hook — the hook UI reports "Failed to run" with the same EEXIST.

Reproduces 100% on my machine across multiple sessions on multiple days. Workaround: use the PowerShell tool instead of Bash — it does not trigger the same setup code path.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

No response

Claude Code Version

2.1.143

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

IntelliJ IDEA terminal

Additional Information

Stale-directory accumulation (related symptom, same root cause):

Each session creates a UUID-named subdirectory under %USERPROFILE%\.claude\session-env\ and nothing ever cleans up. After several days of normal use I had <<ORPHAN_COUNT>> orphan directories, all marked with the Windows ReadOnly attribute, each containing the same 153-byte sessionstart-hook-1.sh. Worth adding a sweep-on-startup or TTL.

Count your own:

(Get-ChildItem "$env:USERPROFILE\.claude\session-env" -Directory).Count

Suggested fix:

Whichever code path creates session-env/<session-id>/ should use idempotent semantics:

  • Node.js: fs.mkdirSync(path, { recursive: true }) instead of fs.mkdirSync(path).
  • Or guard with if (!fs.existsSync(path)) fs.mkdirSync(path).

Sample failing directory contents:

session-env/b09856cb-f292-4edc-b209-b1c8133962d3/
  sessionstart-hook-1.sh    153 bytes    (READ-ONLY directory attribute set)
  └─ contents:
       export CODEX_COMPANION_SESSION_ID='b09856cb-f292-4edc-b209-b1c8133962d3'
       export CLAUDE_PLUGIN_DATA='C:/Users/PC/.claude/plugins/data/codex-openai-codex'

Hook source: the failing hook output above is from the codex@openai-codex plugin's SessionStart hook, but the underlying bug is in the Claude Code harness's session-env setup — any plugin that writes via SessionStart hooks will trigger the same EEXIST pattern, and every Bash tool call hits it regardless of which plugins are installed.


Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] Bash tool and SessionStart hooks fail with EEXIST on Windows due to non-idempotent mkdir of session-env