[BUG] Session resume renders messages in wrong order due to race condition in timestamp logging
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?
Description:
When resuming a session, the UI rendering becomes corrupted. Tool calls from the previous session appear at the bottom of the chat, and all new messages (including new user inputs and assistant responses) appear above them, as if the tool calls are "stuck" at the bottom.
Symptoms:
- Resume a session with claude --resume
- Old tool call results appear at the very bottom
- Send a new message → it appears ABOVE the old tool calls
- Assistant responds → response appears ABOVE the old tool calls
- This continues indefinitely - the old tool calls stay stuck at the bottom while new conversation happens above them
Root Cause (partial):
Investigation revealed a race condition where PostToolUse hook progress messages are logged with timestamps before their parent tool_result messages:
# Buggy case from session logs:
tool_result: timestamp = 03:31:12.786Z uuid = 1618a60c...
hook_progress: timestamp = 03:31:12.763Z parent = 1618a60c... (23ms BEFORE parent!)
However, this timestamp issue alone doesn't fully explain why NEW messages continue to render above old tool calls. There appears to be a secondary issue where the renderer's understanding of the message tree/order becomes persistently corrupted after loading a session with out-of-order timestamps.
What Should Happen?
- On resume: messages should appear in logical conversation order
- After sending new messages: they should appear at the bottom, below all previous content
Error Messages/Logs
Steps to Reproduce
- Configure any PostToolUse hook in settings.json (probably a few which do something I/O, you need to create the race)
- Start a session and trigger a tool call (e.g., ask Claude to call a tool)
- Let Claude respond with text after the tool call
- Exit the session
- Resume with claude --resume
- Observe: tool call appears at bottom, text response above it
- Send a new message
- Observe: new message and response appear ABOVE the old tool call, which stays stuck at bottom
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.7
Claude Code Version
2.1.9
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Disabling PostToolUse hooks prevents the issue from occurring.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗