diff --git a/app/plugins/builtins/mail/services.py b/app/plugins/builtins/mail/services.py index 8027789..517ec61 100644 --- a/app/plugins/builtins/mail/services.py +++ b/app/plugins/builtins/mail/services.py @@ -663,11 +663,21 @@ async def imap_sync_folder( if existing_mail: # If mail has deleted_at but is still on the IMAP server, - # the IMAP delete failed — restore it so it's visible again. - # This prevents mails from being permanently hidden when IMAP delete fails. + # the IMAP delete failed. + # Only restore if the mail is in the SAME folder we're syncing. + # If the mail was moved to Trash in DB (folder_id=Trash) but is + # still in INBOX on IMAP, DON'T restore to INBOX — keep it + # in Trash and let the sync queue retry the IMAP MOVE. if existing_mail.deleted_at is not None: - existing_mail.deleted_at = None - logger.info("imap_sync_folder: restored mail %s (still on IMAP server, delete had failed)", existing_mail.id) + if existing_mail.folder_id == folder.id: + # Mail is in the right folder on IMAP — restore + existing_mail.deleted_at = None + logger.info("imap_sync_folder: restored mail %s (still on IMAP server in correct folder)", existing_mail.id) + else: + # Mail is in a different folder in DB — IMAP move failed + # Don't restore, don't change folder_id — keep in Trash + logger.info("imap_sync_folder: skipping mail %s (deleted, in folder %s but found in %s on IMAP, move failed)", existing_mail.id, existing_mail.folder_id, folder.imap_name) + continue # Update folder_id and imap_uid if mail moved to a different folder if existing_mail.folder_id != folder.id: existing_mail.folder_id = folder.id @@ -1161,10 +1171,21 @@ async def imap_sync_account( if existing_mail: # If mail has deleted_at but is still on the IMAP server, - # the IMAP delete failed — restore it so it's visible again. + # the IMAP delete failed. + # Only restore if the mail is in the SAME folder we're syncing. + # If the mail was moved to Trash in DB (folder_id=Trash) but is + # still in INBOX on IMAP, DON'T restore to INBOX — keep it + # in Trash and let the sync queue retry the IMAP MOVE. if existing_mail.deleted_at is not None: - existing_mail.deleted_at = None - logger.info("imap_sync_account: restored mail %s (still on IMAP server, delete had failed)", existing_mail.id) + if existing_mail.folder_id == folder.id: + # Mail is in the right folder on IMAP — restore + existing_mail.deleted_at = None + logger.info("imap_sync_account: restored mail %s (still on IMAP server in correct folder)", existing_mail.id) + else: + # Mail is in a different folder in DB — IMAP move failed + # Don't restore, don't change folder_id — keep in Trash + logger.info("imap_sync_account: skipping mail %s (deleted, in folder %s but found in %s on IMAP, move failed)", existing_mail.id, existing_mail.folder_id, folder.imap_name) + continue # Track folder moves: update folder_id and imap_uid if the # mail now appears in a different IMAP folder. if existing_mail.folder_id != folder.id: