Bug: Messages display out of order / duplicated in channels #43
Labels
No labels
area:api
area:core
area:docs
area:infra
area:ux
dependencies
documentation
duplicate
good first issue
help wanted
invalid
question
rust
status:complete
status:partial
status:planned
type:bug
type:design
type:feature
type:infra
type:refactor
type:research
type:ux
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
icub3d/decentcom#43
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Migrated from GitHub issue icub3d/decentcom#56
Original Author: @icub3d
Original Date: 2026-04-16T18:43:48Z
Bug: Messages Display Out of Order / Duplicated in Channels
Overview
Channel messages can appear out of order or duplicated. There are three related bugs in
serverStore.tsloadMoreMessagesthat interact with real-time WebSocket events.Root Cause
Bug 1 — Stale
existingoverwrites WebSocket messages (most impactful)In
loadMoreMessages(client/src/stores/serverStore.ts, line 272),existingis captured from the store before the API fetch, then used inside theset()callback after the fetch resolves:Any
MESSAGE_CREATEWebSocket events that arrive during the in-flight fetch are prepended toprev.messages[channelId]byhandleGatewayEvent, but then immediately overwritten whenloadMoreMessagesresolves using the staleexisting. The result is missing messages and apparent ordering gaps.Bug 2 — No deduplication in
loadMoreMessagesIf
loadMoreMessagesis called twice concurrently (e.g., rapid scroll before the guard fires), both calls capture the sameexistingand fetch the same page. Theset()calls produce[...existing, ...samePage, ...existing, ...samePage]— duplicate messages that afterreverse()inMessageListappear as repeated blocks.The
MESSAGE_CREATEWS handler does deduplicate by ID, butloadMoreMessagesdoes not.Bug 3 — No re-sort after merge
After merging API results and live WS messages there is no normalisation step. If any message arrives with an ID that falls in the middle of the existing array (e.g., after a reconnect delivers a backlog), it is prepended to the front regardless of timestamp, producing an out-of-order sequence that
reverse()cannot fix.Requirements
loadMoreMessagesmust useprev.messages[channelId](current state) insideset(), not the stale snapshot captured before the fetchMessageList.reverse()always yields a consistent oldest→newest orderDesign
Component Changes
client/src/stores/serverStore.ts—loadMoreMessages:The same sort-after-merge approach should be applied in the
MESSAGE_CREATEWS handler for robustness (reconnect backlog).Task List
loadMoreMessages: useprev.messages[channelId]insideset()instead of staleexistingloadMoreMessagesMESSAGE_CREATEWS handler for reconnect safetyTest List
loadMoreMessagessurvives and appears in correct positionloadMoreMessagescalls produce no duplicatesOpen Questions
sortMessages) to avoid duplication betweenloadMoreMessagesand the WS handler?loadingMoreRefguard inMessageList.tsxprevents double-scroll-triggered calls at the component level; should a similar guard be added to the store function itself for defence in depth?