[BUG] SessionStart hook output is not visible to the user — only injected as internal context
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?
This creates a problem: the user has no visibility into the loaded state. The model receives the context silently, but cannot "speak first" — it must wait for user input before responding. This results in:
- User opens a session and sees nothing
- User must type something to trigger the model to present the hook's content
- The hook's context is processed twice (once on load, once when the user asks)
## Expected behavior
The hook's output (or a configurable portion of it) should be printed to the user's terminal/screen when the session starts, similar to how a shell login message works. The model can still receive the
context internally, but the user should also see it.
## Current behavior
- Hook runs successfully (
startup hook success) - Output goes to
system-remindercontext only - Nothing is displayed in the user's terminal/UI
- Model cannot initiate a response without user input
## Reproduction
- Configure a
SessionStarthook in.claude/settings.json:
```json
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "cat path/to/checklist.md",
"timeout": 10,
"statusMessage": "Loading workspace state..."
}
]
}
]
}
}
- Open a new Claude Code session
- Observe: no output is shown to the user
- The model has the context but cannot present it until the user types
What Should Happen?
The hook's output (or a configurable portion of it) should be printed to the user's terminal/screen when the session starts, similar to how a shell login message works. The model can still receive the
context internally, but the user should also see it.
Error Messages/Logs
No error — the hook reports "startup hook success" but its output is only injected into system-reminder context, never displayed to the user.
Steps to Reproduce
- Configure a SessionStart hook in .claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "cat path/to/checklist.md",
"timeout": 10,
"statusMessage": "Loading workspace state..."
}
]
}
]
}
}
- Open a new Claude Code session
- Observe: no output is shown to the user on screen
- The model has the context internally but cannot present it until the user types something
- When the user asks, the model processes the context again (double token cost)
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
Last Working Version
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
The core issue is also about token efficiency. The SessionStart hook loads context into the model's system prompt on every session start, consuming tokens. But since the user cannot see this output, they
inevitably ask "what's the status?" — which forces the model to process and repeat the same context again. This results in double token consumption for the same information.
The hook's purpose is to provide a session summary on startup. If the model already has this loaded, it should either:
- Display it to the user automatically (so they don't need to ask), or
- Allow the model to generate an initial response without waiting for user input
Current flow (wasteful):
- Hook loads checklist → tokens consumed (invisible to user)
- User asks "what's the status?" → tokens consumed again
- Model repeats what it already had → redundant
Ideal flow:
- Hook loads checklist → displayed to user on screen OR model responds immediately
- No duplicate processing needed
This is especially relevant for users who rely on SessionStart hooks for project state management across sessions.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗