[BUG] SessionStart hook fires before terminal UI is ready for input
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?
When using SessionStart hooks to signal agent readiness to external orchestration systems (e.g., creating a marker file), the hook fires before the terminal UI is fully initialized. Input sent via tmux send-keys at this point appears in the prompt, but Enter is interpreted as a literal newline instead of submitting. If a delay of 1 second is added between the hook firing and sending input, then Enter does submit the prompt.
What Should Happen?
After SessionStart fires, the terminal UI should be ready to accept input immediately. Its response should not be different if the input is sent immediately vs with a delay of 1 second after the hook fires. Alternately, there could be a separate PromptReady or InputReady hook after SessionStart.
Error Messages/Logs
Steps to Reproduce
Create a file test.sh with this content and run it:
#!/bin/bash
echo "=== Setting up test directory with SessionStart hook ==="
mkdir -p /tmp/claude-hook-test/.claude
cat > /tmp/claude-hook-test/.claude/settings.local.json << 'EOF'
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "touch /tmp/claude-ready"
}
]
}
]
}
}
EOF
echo "=== Starting Claude in tmux session ==="
rm -f /tmp/claude-ready
tmux kill-session -t claude-test 2>/dev/null
tmux new-session -d -s claude-test -c /tmp/claude-hook-test 'claude'
echo "=== Waiting for SessionStart hook to fire ==="
while [ ! -f /tmp/claude-ready ]; do sleep 0.01; done
# Add `sleep 1` here to see the normal behavior without the bug
tmux send-keys -t claude-test -l 'hello world'
tmux send-keys -t claude-test Enter
sleep 0.5
echo "=== Terminal state (note: 'hello world' appears but was not submitted) ==="
tmux capture-pane -t claude-test -p
echo ""
echo "=== To verify, attach to the session: tmux attach -t claude-test ==="
echo "=== Clean up with: tmux kill-session -t claude-test ==="
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.30 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Script output with the bug:
ev@evs-computer ~ % ~/demo.sh
=== Setting up test directory with SessionStart hook ===
=== Starting Claude in tmux session ===
=== Waiting for SessionStart hook to fire ===
=== Terminal state (note: 'hello world' appears but was not submitted) ===
hello world
╭─── Claude Code v2.1.30 ──────────────────────────────────────────────────────╮
│ │ Tips for getting started │
│ Welcome back ev! │ Run /init to create a CLAUDE.md file w… │
│ │ ─────────────────────────────────────── │
│ │ Recent activity │
│ ▐▛███▜▌ │ No recent activity │
│ ▝▜█████▛▘ │ │
│ ▘▘ ▝▝ │ │
│ Opus 4.5 · Claude Team · Imbue │ │
│ /private/tmp/claude-hook-test │ │
╰──────────────────────────────────────────────────────────────────────────────╯
────────────────────────────────────────────────────────────────────────────────
❯ hello world
────────────────────────────────────────────────────────────────────────────────
ctrl+g to edit in Test_editor.sh
=== To verify, attach to the session: tmux attach -t claude-test ===
=== Clean up with: tmux kill-session -t claude-test ===
Script output without the bug:
ev@evs-computer ~ % ~/demo.sh
=== Setting up test directory with SessionStart hook ===
=== Starting Claude in tmux session ===
=== Waiting for SessionStart hook to fire ===
=== Terminal state (note: 'hello world' appears but was not submitted) ===
╭─── Claude Code v2.1.30 ──────────────────────────────────────────────────────╮
│ │ Tips for getting started │
│ Welcome back ev! │ Run /init to create a CLAUDE.md file w… │
│ │ ─────────────────────────────────────── │
│ │ Recent activity │
│ ▐▛███▜▌ │ No recent activity │
│ ▝▜█████▛▘ │ │
│ ▘▘ ▝▝ │ │
│ Opus 4.5 · Claude Team · Imbue │ │
│ /private/tmp/claude-hook-test │ │
╰──────────────────────────────────────────────────────────────────────────────╯
❯ hello world
✶ Shenaniganing…
────────────────────────────────────────────────────────────────────────────────
❯
────────────────────────────────────────────────────────────────────────────────
esc to interrupt
=== To verify, attach to the session: tmux attach -t claude-test ===
=== Clean up with: tmux kill-session -t claude-test ===This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗