Skip to content

Conversation

@EricBlanquer
Copy link
Contributor

@EricBlanquer EricBlanquer commented Jan 18, 2026

Description

Fixes a race condition where user messages would briefly disappear then reappear when sending new messages.

Root Cause

The issue was caused by two independent code paths that could overwrite optimistic UI updates:

  1. App.jsx (line 189): The file watcher checked activeSessions.has(selectedSession.id) but didn't account for temporary new-session-* IDs. This caused externalMessageUpdate to be incremented prematurely, triggering a message reload.

  2. ChatInterface.jsx (line 3139): The useEffect syncing chatMessages with convertedMessages ran even during isLoading, overwriting optimistic UI updates before the server responded.

Changes

App.jsx

  • Added check for temporary session IDs in active session detection
  • Prevents race condition where activeSessions hasn't been updated yet with the real session ID

ChatInterface.jsx

  • Added !isLoading condition to the chatMessages sync useEffect
  • Preserves optimistic UI updates during active message sending

Testing

✅ Tested: Messages now stay visible during the entire send/response cycle without flashing

Why Both Fixes Are Needed

  • The App.jsx fix prevents externalMessageUpdate from triggering the useEffect at line 3102, which calls setChatMessages(converted) directly (bypassing isLoading protection)
  • The ChatInterface.jsx fix protects the useEffect at line 3138 that syncs via convertedMessages

Without both fixes, messages can still flash via the unprotected code path.

Summary by CodeRabbit

  • Bug Fixes
    • Treats newly created/in-flight sessions as active to avoid race-condition updates that could trigger unnecessary reloads.
    • Prevents converted messages from overwriting the optimistic chat UI while data is loading, preserving in-progress message state.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 18, 2026

Walkthrough

Treats temporary session IDs prefixed with new-session- as active in WebSocket update handling to reduce race conditions, and adds an isLoading guard to the effect that applies convertedMessages to chatMessages to avoid overwriting optimistic UI during loads.

Changes

Cohort / File(s) Summary
WebSocket Session Activity Check
src/App.jsx
Extends active-session detection to consider IDs starting with new-session- as active for WebSocket-driven updates, preventing missed updates when activeSessions hasn't yet updated.
Optimistic UI Update Guard
src/components/ChatInterface.jsx
Adds isLoading guard and includes isLoading in the effect dependency array so convertedMessages are not copied into chatMessages while a load is in progress.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • Feature/edit diff #216: Modifies session-handling logic and temporary-session helpers, directly related to the new-session-* active-session handling in this PR.

Poem

🐰
A tiny tag that hops in place,
I chase the race and save the trace,
While loaders hum and messages wait,
My whiskers guard the chat's sweet state,
Hooray — no lost-updates today! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix message flash/disappear on send' directly and clearly describes the main problem being addressed in the PR, matching the core issue of preventing message flashing during send operations.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Fixes a race condition where user messages would briefly disappear then reappear when sending new messages.

Root cause:
1. App.jsx: File watcher checked activeSessions.has(selectedSession.id) but didn't account for temporary new-session-* IDs, causing premature message reloads
2. ChatInterface.jsx: useEffect syncing chatMessages with convertedMessages ran even during isLoading, overwriting optimistic UI updates

Changes:
- App.jsx (line 189): Include temporary session IDs in active session check to prevent race condition
- ChatInterface.jsx (line 3139): Skip chatMessages sync during isLoading to preserve optimistic updates

Tested: Message now stays visible during send/response cycle without flashing
@EricBlanquer EricBlanquer force-pushed the fix/message-flash-on-send branch from 0c04e28 to 703a97c Compare January 18, 2026 02:35
@blackmammoth
Copy link
Collaborator

@EricBlanquer can you also send detailed reproduction steps for this (including which LLM you picked for testing)?

@EricBlanquer
Copy link
Contributor Author

EricBlanquer commented Jan 22, 2026

@blackmammoth

Reproduction steps

Before the fix (message flash/disappear bug)

  1. Start the app and select any project
  2. Open a new session or existing session
  3. Type a message and send it
  4. Bug: The message briefly appears, then disappears for ~500ms, then reappears when the server confirms it

This happens because:

  • The message is added optimistically to the UI
  • A session-change event triggers a reload of messages from the server
  • The server hasn't saved the message yet → the reload overwrites the optimistic message
  • When the server finally saves, another update restores the message

After the fix

  1. Same steps as above
  2. Expected: Message appears immediately and stays visible without flashing

LLM used for testing

Tested with Claude Sonnet 4 (claude-sonnet-4-20250514) via Claude CLI.

The bug is not LLM-specific - it's a race condition in the frontend between optimistic UI updates and session reload events.

send 1, then send 2 : message 2 has disappeared
image

then reappeared

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants