[iOS · Delivery Status] Message remains "Not sent" with "Retry" after a read receipt is received #29

Closed
opened 2026-11-06 16:29:26 +00:00 by asemeniv · 1 comment
Member

[iOS · Delivery Status] Message remains "Not sent" with "Retry" after a read receipt is received
Status: Confirmed behavior defect.
Component: Swift delivery model / failure-state UI.
Related investigation: INVESTIGATION_96_offline_queue_rejection_then_delivery.zip

Summary
A message can receive a delivery failure (resource-constraint) and later be successfully received and read by the recipient. However, after the sender receives remote_status=read for the same message, the UI still shows "Not sent" and "Retry".

This creates an inconsistent state: the recipient has read the message, but the sender is still encouraged to resend it.

Environment
A (sender): iPhone 13 Pro Max, iOS 26.7.1, testman421@another.im
B (recipient): iPhone 17 Pro Max, iOS 27.2, testman435@another.im
App: v1.1.0 build 96 (feat/ui-redesign@e945d7cc)
libtacky: v1.2.0-rc4
1:1 OMEMO chat
Steps to reproduce
Send a message from A to B while B is suspended/locked.
The message receives a resource-constraint failure indicating that the offline message queue is full.
Resume B, open the chat, and read the message.
Verify that A receives remote_status=read for the same message ID.
Check the message status on A.
Expected result
Once the same message has been received and read, the UI should show a final state consistent with the actual delivery. A previous delivery-stage failure should not leave the message marked as "Not sent" with an unconditional "Retry" action.

Actual result
Both affected messages received remote_status=read at 15:55:06 UTC, and the messages were present on B. However, at 15:58 UTC, A still displayed both messages in red as "Not sent" with "Retry".

No retry was performed during this test.

Relevant diagnostics
For both affected messages:

A recorded server_status=failed with fail_reason=resource-constraint.
The failure referred to the same message IDs/timestamps that later received remote_status=read.
B received both messages after reconnecting and later marked the conversation as displayed.
Code observation
In revision e945d7cc:

DeliveryChange.applied preserves the previous failed server state when an update contains only a remote status.
TranscriptWindow clears failReason only when delivery.server is updated.
As a result, a read update without a new server status does not clear the previous failure state in the current transcript.

This behavior is consistent with the observed logs and UI, although an independent reproduction and diagnostic stack trace are not available.

Retest criteria
Reproduce a failure followed by successful delivery and read for the same message ID.
Verify that the final UI state no longer shows the stale "Not sent" / "Retry" state.
Repeat after navigating away and back and after restarting the app.
Verify that genuinely undelivered messages without a receipt still retain the appropriate failure and retry behavior.

[iOS · Delivery Status] Message remains "Not sent" with "Retry" after a read receipt is received Status: Confirmed behavior defect. Component: Swift delivery model / failure-state UI. Related investigation: INVESTIGATION_96_offline_queue_rejection_then_delivery.zip Summary A message can receive a delivery failure (resource-constraint) and later be successfully received and read by the recipient. However, after the sender receives remote_status=read for the same message, the UI still shows "Not sent" and "Retry". This creates an inconsistent state: the recipient has read the message, but the sender is still encouraged to resend it. Environment A (sender): iPhone 13 Pro Max, iOS 26.7.1, testman421@another.im B (recipient): iPhone 17 Pro Max, iOS 27.2, testman435@another.im App: v1.1.0 build 96 (feat/ui-redesign@e945d7cc) libtacky: v1.2.0-rc4 1:1 OMEMO chat Steps to reproduce Send a message from A to B while B is suspended/locked. The message receives a resource-constraint failure indicating that the offline message queue is full. Resume B, open the chat, and read the message. Verify that A receives remote_status=read for the same message ID. Check the message status on A. Expected result Once the same message has been received and read, the UI should show a final state consistent with the actual delivery. A previous delivery-stage failure should not leave the message marked as "Not sent" with an unconditional "Retry" action. Actual result Both affected messages received remote_status=read at 15:55:06 UTC, and the messages were present on B. However, at 15:58 UTC, A still displayed both messages in red as "Not sent" with "Retry". No retry was performed during this test. Relevant diagnostics For both affected messages: A recorded server_status=failed with fail_reason=resource-constraint. The failure referred to the same message IDs/timestamps that later received remote_status=read. B received both messages after reconnecting and later marked the conversation as displayed. Code observation In revision e945d7cc: DeliveryChange.applied preserves the previous failed server state when an update contains only a remote status. TranscriptWindow clears failReason only when delivery.server is updated. As a result, a read update without a new server status does not clear the previous failure state in the current transcript. This behavior is consistent with the observed logs and UI, although an independent reproduction and diagnostic stack trace are not available. Retest criteria Reproduce a failure followed by successful delivery and read for the same message ID. Verify that the final UI state no longer shows the stale "Not sent" / "Retry" state. Repeat after navigating away and back and after restarting the app. Verify that genuinely undelivered messages without a receipt still retain the appropriate failure and retry behavior.
Contributor

Moved to another-im/libtacky#20 with the analysis of the cause and a proposed fix: it is libtacky's to change. Closing here.

Moved to another-im/libtacky#20 with the analysis of the cause and a proposed fix: it is libtacky's to change. Closing here.
fmodf closed this issue 2026-11-07 08:55:17 +00:00
Sign in to join this conversation.
No labels
done
fixed
returned
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
another-im/anotherim-swift#29
No description provided.