Repository navigation
fix(imp): invalidate search cache when mailboxes change - #63
Merged
Merged
Conversation
Refresh virtual search mailboxes after delete, move, and expunge so stale session results and BUIDs no longer appear after messages leave the inbox. Tie search viewport cache IDs to per-query generation counters and let changed() detect search updates like normal mailboxes. Handle unresolved message indices in IMP_Contents when a browser BUID no longer maps to a mailbox.
ralflang
approved these changes
Jun 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix stale IMP search results after delete/move/expunge
Summary
changed()detects stale search results.Problem
When messages were deleted from the inbox (moved to Trash or expunged), IMP search could still list them. Clicking such a stale result caused fatal errors in
horde.log:Root cause: search results are stored as a virtual mailbox (
impsearch…) in the session. That list was cached with a static cache ID ('1') that never changed when underlying folders were modified. Additionally,IMP_Ajax_Application::changed()skipped automatic refresh for search mailboxes unlessforceUpdatewas set.Stale browser BUIDs could no longer be resolved to mailbox/UID pairs (
fromBuids()returned empty indices), leavinggetMailbox()asnulland crashingIMP_Contents::_fetchData().Solution
Search cache invalidation
Add
IMP_Search::invalidateMailboxes()to rebuild affected search/virtual-folder lists when folder contents change. Called from:IMP_Indices::delete()— after successful delete or move-to-trashIMP_Indices::copy()— onmoveIMP_Mailbox::expunge()Only mailboxes actually modified are tracked; invalidation runs only after successful IMAP operations.
Per-query cache generation
Add a
_cacheGencounter onIMP_Search_Query, bumped byinvalidateCache(). Search mailbox_getCacheID()now includes this generation alongside sort/hide-deleted preferences, so the viewport cache ID changes when results are invalidated.Remove the search-only exception in
IMP_Ajax_Application::changed(). Re-checkchanged()indeleteMsgs()after deletion so the viewport refreshes when the search cache ID has moved.Defensive message load
In
IMP_Contents::_fetchData(), throwIMP_Exceptionwhen indices resolve to no mailbox (before the IMAPtryblock).showMessage()already catches this and refreshes the viewport instead of fatalling.Files changed
lib/Search/Query.php— cache generation counter, serializationlib/Search.php—invalidateMailboxes(),_queryAffected()lib/Mailbox.php— dynamic search_getCacheID(), expunge hooklib/Indices.php— invalidate on delete/movelib/Ajax/Application.php— remove searchchanged()bypass, re-check after deletelib/Contents.php— guard against unresolved BUIDsTest plan
horde.log.$sortprefwarnings inhorde.logwhen opening or refreshing search mailboxes.