[BUG] Stop hook fails with EEXIST when plugin data directory already exists
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?
Stop hooks from plugins fail with EEXIST: file already exists, mkdir when the plugin data directory already exists. The error occurs on every stop hook invocation after the first run.
This is the same root cause as several other EEXIST bugs (#33118, #36919, #37306) — all are missing { recursive: true } on mkdir calls. Closing #39108 as a duplicate in favor of this report.
What Should Happen?
The plugin data directory creation should use recursive/idempotent mkdir (fs.mkdir with { recursive: true }) so it doesn't fail if the directory already exists.
Error Messages/Logs
Ran 1 stop hook (ctrl+o to expand)
⎿ Stop hook error: Failed to run: EEXIST: file already exists, mkdir
'C:\Users\PC\.claude\plugins\data\qingyi-qingyi'
The directory already exists from a previous session:
$ ls ~/.claude/plugins/data/
qingyi-qingyi/
superpowers-claude-plugins-official/
Steps to Reproduce
- Install a plugin that uses a stop hook
- Run a Claude Code session — stop hook works on first run (creates data dir)
- Run another session — stop hook fails because directory already exists
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.79
Claude Code Version
2.1.85
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
IntelliJ IDEA terminal
Additional Information
The hook itself never executes — the error is in the plugin infrastructure before the hook runs. The fix should be a one-line change: use fs.mkdir(path, { recursive: true }) instead of fs.mkdir(path) when creating the plugin data directory.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗