Stop the unread card offering mail that was read and deleted

FixEmailService
Ya
27 Agosti 2026, 01:14 UTC
Mwandishi
kamo
Ahadi ya
7bbb9a0

The home-page unread-mail widget reads email_metadata.search_index directly — it must not spend an IMAP connection, which is the whole reason it exists — and that index only ever learned what a folder HOLDS. It was written as a side effect of listing mail, and a listing reports the messages that are there; nothing in it can say a message has gone. So a message that was read and then deleted left its row behind for ever, frozen at the flags it arrived with. Neither event was recorded: not the read, because a flag change never re-indexed anything, and not the delete, because the message stopped appearing in any page. The row stayed unread and the widget went on offering it. The reporter's index held seven such INBOX rows, every one of them also present in Trash and marked read there — mail they had dealt with eleven to twenty days earlier, still on their dashboard. Fixed at both ends: * every path that moves, deletes or re-flags a message now tells the index in the same breath — single message, batch selection, filter rule, conversation read, conversation star, spam report. For a delete this happens before the mailbox-changed event, since that event is what makes the home page re-read the widget; * a synced page that provably covers the WHOLE folder now drops the rows for messages it did not contain, which catches mail read or deleted from a phone or another client, and clears rows orphaned before any of this existed. "Provably" is exact agreement with the server's own message count, not a short page: a provider is free to cap a page at its own maximum, so short means "the provider stopped", which is not "the folder ended". Every other case falls through and reconciles next time. The index is also the search corpus, so a wrong deletion here loses real mail from search — the safety argument is coversWholeFolder(), which is pure and tested from the direction of "can it say yes when it must not". Reconciling runs before the checkpoint is written, and is the one call in MailIndexMaintenance allowed to throw. A checkpoint asserts the index describes the folder correctly at that modseq; writing one over an index still holding rows for deleted mail would let the index-backed message list serve those rows back as mail. A failed reconcile takes no checkpoint, which means resync — the direction this whole path fails in. Shared mailboxes are deliberately untouched: index rows are keyed by member and UID, UIDs are unique within a mailbox rather than across them, and re-flagging UID 42 of a shared mailbox against a member would hit whatever their own inbox holds at 42.

Mabadiliko yote

Je, unaona nini kuhusu usafiri?

Kila moja ya hizi updates ardhi katika nafasi yako ya kazi moja kwa moja. Kuanza bure na kuangalia kukua wiki baada ya wiki.

Kuwa Huru MileleMtazamo wa bei