[BUG] SessionStart/UserPromptSubmit hooks receive transcript_path before project directory exists (first session in new project)
Bug Description
When opening the first-ever Claude Code session in a project directory that has never had a session before, the ~/.claude/projects/<encoded-path>/ directory does not yet exist when SessionStart and UserPromptSubmit hooks fire. Hooks that use the transcript_path field from the hook payload to derive the project directory (via dirname) fail because the directory hasn't been created yet.
This produces visible SessionStart:startup hook error and UserPromptSubmit hook error messages in the terminal. Subsequent hook events (PreToolUse, PostToolUse, etc.) work fine because Claude Code has created the directory by that point.
Steps to Reproduce
- Find or create a project directory that has never had a Claude Code session (i.e., no corresponding
~/.claude/projects/<encoded-path>/directory exists) - Have a plugin or hook that writes to the directory derived from
transcript_path(e.g., theclaude-statusmarketplace plugin) - Start a new session in that directory
- Observe
SessionStart:startup hook erroron startup - Submit a prompt
- Observe
UserPromptSubmit hook error - All subsequent hook events succeed normally
Expected Behavior
The project directory referenced by transcript_path should exist before SessionStart hooks fire, so hooks can safely write files there from the first event.
Workaround
Hooks can defensively mkdir -p "$(dirname "$TRANSCRIPT_PATH")" before writing, but this is something every hook author would need to remember to do.
Environment Info
- Platform: darwin (macOS 26.4)
- Version: 2.1.88
- Affected hooks:
SessionStart,UserPromptSubmit(first invocation only) - Reproduced with:
claude-statusmarketplace plugin (v1.1.5)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗