[BUG] PreToolUse/PostToolUse hook error: Cannot find module session-state.cjs
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 happened
Multiple hook events (PreToolUse:Bash, PreToolUse:Read, PostToolUse:Bash, and the stop hook) throw a MODULE_NOT_FOUND error referencing a session-state.cjs file that doesn't exist in the project's .claude/hooks/ directory.
The error fires on nearly every tool call, flooding the output with non-blocking warnings:
PreToolUse:Bash hook error Failed with non-blocking status code:
node:internal/modules/cjs/loader:1252
throw err;
^
Error: Cannot find module '/Users/uditgoenka/Desktop/workspace/social/.claude/hooks/session-state.cjs'
at Function._resolveFilename (node:internal/modules/cjs/loader:1249:15)
at Function._load (node:internal/modules/cjs/loader:1075:27)
at TracingChannel.traceSync (node:diagnostics_channel:315:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:218:24)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5)
at node:internal/main/run_main_module:36:49 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Expected behavior
If a hook references a file that doesn't exist, Claude Code should either:
- Skip the hook silently (or with a single one-time warning), OR
- Validate hook paths at startup and report missing files once, not on every tool call
Actual behavior
The error fires on every PreToolUse, PostToolUse, and Stop event — dozens of times per session — cluttering the output. The hook is configured in global settings (~/.claude/settings.json) but references a per-project path ($CLAUDE_PROJECT_DIR/.claude/hooks/session-state.cjs) that doesn't exist in every project.
How to reproduce
- Add a hook in
~/.claude/settings.json:
{
"hooks": {
"Stop": [{ "hooks": [{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-state.cjs" }] }]
}
}
- Open Claude Code in a project that does NOT have
.claude/hooks/session-state.cjs - Run any command — observe the error fires on every tool call
Suggested fix
- Hooks referencing
$CLAUDE_PROJECT_DIRpaths should gracefully handle missing files - A single warning at session start ("Hook file not found: X — skipping") would be much better than per-event errors
- Or: resolve
$CLAUDE_PROJECT_DIRat registration time and skip hooks when the target file doesn't exist
Environment
- Claude Code version: 2.1.123
- Platform: macOS (Darwin 25.3.0)
- Node.js: v22.11.0
- Shell: zsh
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗