[BUG] Session resume renders messages in wrong order due to race condition in timestamp logging

Resolved 💬 2 comments Opened Jan 16, 2026 by hb-man Closed Jan 16, 2026

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:

  1. Resume a session with claude --resume
  2. Old tool call results appear at the very bottom
  3. Send a new message → it appears ABOVE the old tool calls
  4. Assistant responds → response appears ABOVE the old tool calls
  5. 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

  1. Configure any PostToolUse hook in settings.json (probably a few which do something I/O, you need to create the race)
  2. Start a session and trigger a tool call (e.g., ask Claude to call a tool)
  3. Let Claude respond with text after the tool call
  4. Exit the session
  5. Resume with claude --resume
  6. Observe: tool call appears at bottom, text response above it
  7. Send a new message
  8. 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.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗