Prevent calling MarkRead on the current user's own unsynced last message#6431
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
MarkRead on the current user's own unsynced last message
SDK Size Comparison 📏
|
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe PR adds sync-status gating to ChangesSync-Status Read Guard
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
🚀 Available in v6.37.4 |


Goal
AND-1173 — In an otherwise-empty channel, sending a message while it is still in-flight (optimistic,
SyncStatus.IN_PROGRESS) and callingmarkLastMessageReadcauses the server to persistlast_read_message_id = "". From the server's perspective the channel is empty at that moment, so it has no message to anchor the read state to. This can causes issues in integrations where they expect a validlast_read_message_idvalue.Implementation
In
MessageListController.markLastMessageRead(), gate themarkReadcall on the bottom message: if it is authored by the current user and itssyncStatus != COMPLETED, log and return early instead of issuing the API call. Peer messages are not affected —syncStatusis a local-only field and peer messages keep the data-class default, so the gate is intentionally scoped to messages owned by the current user.UI Changes
No UI changes.
Testing
Unit tests added in
MessageListControllerTests:When current user's last message is COMPLETED markLastMessageRead should invoke markRead— happy path,lastSeenMessageIdis updated.When current user's last message is not COMPLETED markLastMessageRead should not invoke markRead— gated path, no API call,lastSeenMessageIdstays null.When peer's last message is not COMPLETED markLastMessageRead should still invoke markRead— guards against the gate over-matching peer messages that carry the defaultsyncStatus.The existing
When repetitive markLastMessageRead calls appear only single API call should be senttest was updated to seed messages withSyncStatus.COMPLETEDso it continues to exercise the dedupe path rather than the new gate.Manual repro: open an empty channel as a user with no prior reads, send a message, observe
markReadrequest in logs / on the backend before vs. after this fix.Summary by CodeRabbit