[BUG] InstructionsLoaded hook does not fire for User and root Project CLAUDE.md at session start
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 InstructionsLoaded hook does not fire for User CLAUDE.md (~/.claude/CLAUDE.md) or root Project CLAUDE.md at session start. It only fires for nested_traversal events (lazy loads when Claude reads files in subdirectories with their own CLAUDE.md).
The files are loaded into context — Claude can reference their contents when asked — but the hook simply never fires for them.
Expected Behavior
Per the docs, InstructionsLoaded should fire at session start for eagerly-loaded files with load_reason: "session_start". Events for User CLAUDE.md (memory_type: "User") and root Project CLAUDE.md (memory_type: "Project") should appear.
Actual Behavior
Only nested_traversal events fire. No session_start events are ever emitted.
Reproduction Steps
- Create
~/.claude/CLAUDE.mdwith some content - Create a project with
CLAUDE.mdat root and a subdirectoryapps/web/CLAUDE.md - Configure the
InstructionsLoadedhook to log all events:
{
"hooks": {
"InstructionsLoaded": [
{
"hooks": [
{
"type": "command",
"command": "cat >> /tmp/instructions-loaded.jsonl",
"timeout": 5,
"async": true
}
]
}
]
}
}
- Start a new Claude Code session in the project
- Navigate into subdirectories so
nested_traversalfires - Inspect
/tmp/instructions-loaded.jsonl
Expected: Events with load_reason: "session_start" for User and root Project CLAUDE.md, plus nested_traversal for subdirectory CLAUDE.md files.
Actual: Only nested_traversal events appear. Example:
{"session_id":"23c82a42-...","load_reason":"nested_traversal","memory_type":"Project","file_path":"/path/to/apps/web/CLAUDE.md"}
{"session_id":"23c82a42-...","load_reason":"nested_traversal","memory_type":"Project","file_path":"/path/to/apps/web/src/components/CLAUDE.md"}
No events with load_reason: "session_start" are present.
Verification
- Confirmed the files are loaded into context (asked Claude to reference CLAUDE.md contents — it could)
- Checked both an OTLP pipeline (Loki) and a local JSONL audit log — both missing
session_startevents - Other hooks (SubagentStart, SubagentStop, Notification, etc.) all work correctly
- The hook config has no
matcherfield (fires on all events per the docs)
Environment
- Claude Code version: 2.1.72
- OS: macOS (Darwin 25.2.0)
- Shell: zsh
Related Issues
- #30973 — InstructionsLoaded does not fire after compaction (different trigger, same hook)
- #31017 — InstructionsLoaded does not fire on /clear (different trigger, same hook)
Note: Both #30973 and #30897 show evidence that session_start events DO work for other users, suggesting this may be environment-specific or a regression.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗