Stable uid on IMAP #539
Open
opened 2026-06-08 06:10:16 +00:00 by guettli
·
5 comments
No Branch/Tag Specified
main
issue-563-agentloop-validation
dummy-pr-test
issue-560-fix-firebase-run-url
issue-539-stable-imap-uid
issue-533-shared-email-list
plan-issue-555
drop-nix
plan-issue-484
plan-issue-539
plan-issue-535
plan-issue-474
plan-issue-533
fix-dagger-engineless-precommit
issue-521-fix-deploy-yml-wait-time-api
issue-502-fix-email-id-collision-mailbox
issue-492-eliminate-duplicate-build-runner
issue-494-website-change-detection
issue-491-parallelize-check
issue-478-fix-stalwart-dual-stack-bind
issue-475-allowed-addresses-glob
issue-473-search-result-reorder
issue-453-update-agentloop-defaults
issue-466-structured-search
issue-505-exclude-chaos-monkey-from-regular-ci
issue-509-fix-search-result-sorting
fix-ink-sparkle-remaining-tests
issue-506-fix-search-emails-tests
issue-504-runner-wait-time
issue-488-search-notes
issue-472-changelog-issue-links
issue-501-folder-search-local-sqlite
issue-486-fix-stale-test-shader-mismatch
fix/prevent-settled-search-rerun-473
issue-467-fix-search-stale-results
issue-446-installed-versions-in-changelog
issue-462-fix-pr
issue-448-chaos-monkey-test
issue-436-notes-on-emails
issue-429-unify-mail-display
issue-422-move-to-folder-create-new
issue-414-ensure-not-run-as-root
issue-424-unify-email-list-views
issue-419-trusted-senders-page
issue-425-fix-prs
test-foo
issue-421-bug-report
issue-383-fix-ci
issue-394-fix-deploy-flutter-version
issue-391-fix-ci-double-trigger
issue-376-combined-inbox-v2
issue-376-combined-inbox
issue-384-fix-open-prs
sops-migrate
issue-339-safe-first-on-imap-fetch
issue-340-try-catch-measure-height
issue-342-pin-intl-version
issue-341-guard-threademails-last
issue-335-agentloop-code-test
issue-329-fix
issue-315-fix
issue-320-fix
issue-325-fix
issue-312-fix
issue-311-fix
issue-305-fix
issue-304-fix
issue-299-fix
issue-300-fix
issue-298-fix
issue-296-fix
issue-294-fix
issue-289-fix
issue-288-fix
issue-287-fix
issue-286-fix
issue-277-fix
issue-282-fix
issue-280-fix
issue-272-fix
issue-268-fix
issue-267-fix
issue-266-fix
issue-258-fix
issue-260-fix
issue-257-fix
issue-253-fix
issue-216-fix
issue-251-fix
issue-249-fix
issue-question-fixes
issue-235-fix
issue-236-fix-v2
issue-237-fix
issue-236-fix
issue-228-fix
issue-217-fix
issue-214-fix
issue-213-fix
issue-208-fix
issue-205-fix
issue-204-fix
issue-203-fix
issue-202-fix
issue-129-fix
issue-161-fix
issue-160-fix
issue-201-fix
issue-210-fix
issue-198-fix
issue-200-fix
issue-144-fix
issue-199-fix
fix/playstore-upload-use-requests
issue-193-fix
issue-186-fix
issue-185-fix
issue-192-fix
issue-183-fix
issue-175-fix
issue-172-fix
issue-171-fix
issue-167-fix
issue-136-fix
issue-162-fix
issue-179-fix
issue-155-fix
issue-154-fix
issue-152-fix
issue-151-fix
issue-141-fix
issue-150-fix
issue-164-fix
migrate-to-dagger
task/d1-ci-matrix
task/a4-typeconverter-json
task/u7-onboarding-walkthrough
task/d3-sync-doc
task/a5-layer-boundary-lint
task/t5-golden-tests
task/p5-date-cache
task/s4-link-handling
task/p3-html-parse-isolate
task/u8-mark-all-read
task/u3-recent-searches
task/a3-jmap-injectable-http-client
task/r5-tls-error-handling
fix/playstore-redirect-retry
task/t3-repository-contract-tests
task/p2-email-list-pagination
task/p1-fts5-search
fix/playstore-upload-timeout
task/a1-email-detail-notifier
fix/upgrade-workmanager-0.9
fix/android-core-library-desugaring
task/p4-db-indexes
task/r3-html-error-boundary
task/d2-check-coverage
task/a2-email-tile
task/t4-migration-tests
task/t2-widget-tests
task/t1-email-repo-coverage
task/u6-connection-status
task/u4-push-notifications
task/u2-draft-sync
task/u1-list-unsubscribe
task/s2-hostname-validation
task/r6-reliability-fuzz-tests
task/r4-sync-error-banner
task/r2-force-resync
task/r1-undo-history-persistence
No results found.
Labels
Clear labels
NeedSupervisor
State/InProgress
State/Later
State/Planned
automerge
ci-failure
do-not-merge
loop/code
loop/code-ci-pending
loop/code-done
loop/code-in-process
loop/merge
loop/merge-done
loop/merge-in-process
loop/plan
loop/plan-done
loop/plan-in-process
Issue escalated to a human supervisor; agentloop will skip it until cleared.
Eligible for automatic merge by CI
Issue opened by agentloop to track a failing CI workflow; used for deduplication.
Plan PR — review only, do not merge.
Add to run the built-in "code" prompt; override at prompts/code.md.
Prompt "code" finished; waiting for the PR's CI to pass before advancing.
Prompt "code" finished successfully.
Agent for the "code" prompt is currently running on this issue.
Managed by agentloop
Managed by agentloop
Managed by agentloop
Add to run the built-in "plan" prompt; override at prompts/plan.md.
Prompt "plan" finished successfully.
Agent for the "plan" prompt is currently running on this issue.
No labels
loop/code-done
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: guettli/sharedinbox#539
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
View and comment on the plan
When a message gets moved in IMAP, then the old uid gets lost.
Afaik there is no reliable way to address the mail in the new folder. Research that. Is there a way?
We could do that trick: we create a DB table of expected new mails in a folder. On next sync the moved message appears as new. When the massageID matches, then we can update the uid.
Then we can update the UndoLog
Does that make sense?
Agentloop runs
PR opened: https://codeberg.org/guettli/sharedinbox/pulls/558
Summary
Implemented stable IMAP identity across
MOVEoperations. The fix uses the RFC 4315COPYUIDresponse code that modern UIDPLUS servers attach toMOVE/COPY(already exposed byenough_mail), with aUID SEARCH HEADER Message-IDfallback for servers without UIDPLUS.What changed:
_applyPendingChangeImapnow captures the result of everyuidMovecall and feeds it into a new_remapEmailAfterImapMovehelper.accountId:srcMailbox:srcUidtoaccountId:destMailbox:newUid, cascading the change toemail_bodies,threads,pending_changes, andundo_actionsso cached bodies and queued undo entries keep tracking the message._reconcileDeletedImapnow skips rows whosemove/snooze/unsnoozeis still inpending_changes, fixing a latent race where the optimistically-moved row could be wiped before the server flush ran.SYNC.mdandDB-SYNC.mddocument the new behavior.This is simpler than the "predicted mail" table sketched in the issue: the response code path is reliable and the search fallback is bounded and stateless — no new schema needed.
Verified via
flutter analyze(clean) andflutter test test/unit(all 382 unit tests pass, including 4 new tests covering COPYUID remap, header-search fallback, undo_actions rewrite, and the reconciliation guard). Backend tests need a real Stalwart instance and will be exercised by CI.PR: https://codeberg.org/guettli/sharedinbox/pulls/558
agentloop · agent: claude
agentloop: CI failed on PR #558; resuming acpx session to fix (attempt 1/3).
agentloop: agent hit the Anthropic quota; pausing this loop until 2026-06-10T17:40:00Z and will retry then. (Internal error: You're out of extra usage · resets 5:40pm (UTC) (account: tilldu@googlemail.com))
Pushed the fix to the PR.
CI was failing on
dart analyze --fatal-infos(stricter than my localflutter analyze), specificallyrequire_trailing_commason a map literal in the new "no UIDPLUS" test. Pulled the literal into aconstmap with a trailing comma. Verified locally withflutter analyze --fatal-infoson the changed files (clean) and re-ranflutter test test/unit/email_repository_impl_test.dart(all 77 tests pass). Pushed as29bc403onissue-539-stable-imap-uid. PR: https://codeberg.org/guettli/sharedinbox/pulls/558agentloop · agent: claude
Pushed the fix to the PR.
CI was failing on
dart analyze --fatal-infos(stricter than my localflutter analyze), specificallyrequire_trailing_commason a map literal in the new "no UIDPLUS" test. Pulled the literal into aconstmap with a trailing comma. Verified locally withflutter analyze --fatal-infoson the changed files (clean) and re-ranflutter test test/unit/email_repository_impl_test.dart(all 77 tests pass). Pushed as29bc403onissue-539-stable-imap-uid. PR: https://codeberg.org/guettli/sharedinbox/pulls/558agentloop · agent: claude