Skip to content

fix(reactions): leave unsent messages out of the reaction refresh - #1676

Merged
bmc08gt merged 1 commit into
code/cashfrom
fix/reaction-refresh-pending-ids
Oct 5, 2026
Merged

bmc08gt merged 1 commit into
code/cashfrom
fix/reaction-refresh-pending-ids

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

A pending or failed send is stored with messageId = -(now), and MessageList.newestFirstMessageIds() collects every row's id for the reaction refresh. One negative id fails the MessageId rule (>= 1) for the whole getReactionSummariesByIds batch. A failed send in the newest 60 rows therefore blocked the open/resume refresh for that chat until the send was retried or deleted. The new-rows hook also sent the unsent row's id on its own as soon as it appeared.

Seen in the log of Bugsnag 6ac2ccde396a2e952063917a (2026.9.4): ValidationException: message_ids.message_ids[0].value: must be greater than or equal to 1, a second after a send failed with Denied. Deobfuscated, the stack runs ChatViewModel (RefreshReactionIds) → ReactionsDelegate.refreshReactions → ChatMessagingController → ChatMessagingService.

ReactionRefreshPlanner now drops ids below 1 in initialWindow and forLoadedPage. The window filters before it takes, so it still covers 60 real messages. An unsent message has no reactions to fetch; its real id arrives with the server echo and pages in as a new id.

iOS is unaffected: its unsent rows use MessageID.unassigned (UInt64.max).

Related: #1671 fixes the crash in the same event.

A pending or failed send is stored with messageId = -(now), and
MessageList collects every row's id for the refresh. One in a batch fails
the MessageId rule (>= 1) for the whole getReactionSummariesByIds request,
so a failed send in the newest 60 rows blocked the open/resume refresh for
that chat until it was retried or deleted. Seen in the log of Bugsnag
6ac2ccde396a2e952063917a: "message_ids[0].value: must be greater than or
equal to 1" a second after a send failed.

ReactionRefreshPlanner now drops ids below 1 in both entry points. The real
id arrives with the server echo and pages in as a new id.
@bmc08gt bmc08gt self-assigned this Oct 5, 2026
@github-actions github-actions Bot added the type: fix Bug fix label Oct 5, 2026
@bmc08gt
bmc08gt merged commit c09cdc2 into code/cash Oct 5, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant