Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syncronization of previously deleted/moved emails: 'failed to label messages: Message does not exist' #169

Open
thekix opened this issue Nov 22, 2023 · 0 comments

Comments

@thekix
Copy link
Member

thekix commented Nov 22, 2023

I have a problem with mails deleted in the IMAP server and in the local files. If I sync my mail using offlineimap, then I delete one mail from the inbox in the computer and delete the same mail in the server (with webmail/app) and finally I sync my mail again using offlineimap, offlineimap crash with the log attached.

Offlineimap is trying to move a mail in the server but the mail was previously deleted. Then, It crash. If I am running the offlineimap continuosly, I need wait three minutes to sync again, and offlineimap crash again with every mail deleted. For example, If I remove 10 mails using my mobile phone app, I need wait 30 minutes to get my mail sync in the computer. Finally, offlineimap crashes and terminates.

More people can reproduce the same problem??

The problem is between lines 706-728 in the file offlineimap/folder/IMAP.py:

                try:
                    (typ, dat) = imapobj.append(
                        self.getfullIMAPname(),
                        imaputil.flagsmaildir2imap(flags),
                        date,  msg.as_bytes(policy=output_policy))
                    # This should only catch 'NO' responses since append()
                    # will raise an exception for 'BAD' responses:
                    if typ != 'OK':
                        # For example, Groupwise IMAP server
                        # can return something like:
                        #
                        #   NO APPEND The 1500 MB storage limit \
                        #   has been exceeded.
                        #
                        # In this case, we should immediately abort
                        # the repository sync and continue
                        # with the next account.
                        err_msg = \
                            "Saving msg (%s) in folder '%s', " \
                            "repository '%s' failed (abort). " \
                            "Server responded: %s %s\n" % \
                            (msg_id, self, self.getrepository(), typ, dat)
                        raise OfflineImapError(err_msg, OfflineImapError.ERROR.REPO)

I cannot find information about this message (failed to label messages: Message does not exist (Code=2501, Status=0)) in the RFC9051 (https://datatracker.ietf.org/doc/html/rfc9051).

Solve the problem could be easy, something like (CODE NOT TESTED):

if typ != 'OK':  # <- Line already in the file
    if "Message does not exist" in dat:
        # Message probably previously moved, we return 0
        # The mail will be deleted in local and synced in the next run
        return 0
# For example, Groupwise IMAP server  # <- Line already in the file
# can return something like:  # <- Line already in the file

We return 0 because in the Basy.py file we have (lines 828 - 847), we call in 828 (first line) the call to "savemessage" and check the return code equal to 0 in line 840 (elif new_uid == 0:)

            new_uid = dstfolder.savemessage(uid, message, flags, rtime)
            if new_uid > 0:
                if new_uid != uid:
                    # Got new UID, change the local uid to match the new one.
                    self.change_message_uid(uid, new_uid)
                    statusfolder.deletemessage(uid)
                    # Got new UID, change the local uid.
                # Save uploaded status in the statusfolder.
                statusfolder.savemessage(new_uid, message, flags, rtime)
                # Check whether the mail has been seen.
                if 'S' not in flags:
                    self.have_newmail = True
            elif new_uid == 0:
                # Message was stored to dstfolder, but we can't find it's UID
                # This means we can't link current message to the one created
                # in IMAP. So we just delete local message and on next run
                # we'll sync it back
                # XXX This could cause infinite loop on syncing between two
                # IMAP servers ...
                self.deletemessage(uid)

What do you think? Comments are appreciated.

Best regards,
kix

General informations

  • system/distribution (with version):
  • offlineimap version (offlineimap -V): offlineimap v8.0.0, imaplib2 v3.05,
  • Python version: Python v3.11.6

Logs, error

 *** Finished account 'Mail' in 0:29
INFO:OfflineImap:*** Finished account 'Mail' in 0:29
 ERROR: Exceptions occurred during the run!
WARNING:OfflineImap:ERROR: Exceptions occurred during the run!
 ERROR: offlineimap.error.OfflineImapError: Saving msg (<1234567890@xxxx>) in folder 'Trash', repository 'Remote-Mail' failed (abort). Server responded: NO [b'failed to label messages: Message does not exist (Code=2501, Status=0)']


WARNING:OfflineImap:ERROR: offlineimap.error.OfflineImapError: Saving msg (<1234567890@xxxx>) in folder 'Trash', repository 'Remote-Mail' failed (abort). Server responded: NO [b'failed to label messages: Message does not exist (Code=2501, Status=0)']


 
Traceback:
  File "/home/kix/src/offlineimap3/offlineimap/accounts.py", line 298, in syncrunner
    self.__sync()
  File "/home/kix/src/offlineimap3/offlineimap/accounts.py", line 424, in __sync
    syncfolder(self, remotefolder, quick)
  File "/home/kix/src/offlineimap3/offlineimap/accounts.py", line 669, in syncfolder
    localfolder.syncmessagesto(remotefolder, statusfolder)
  File "/home/kix/src/offlineimap3/offlineimap/folder/Base.py", line 1177, in syncmessagesto
    action(dstfolder, statusfolder)
  File "/home/kix/src/offlineimap3/offlineimap/folder/Base.py", line 1004, in __syncmessagesto_copy
    self.copymessageto(uid, dstfolder, statusfolder, register=0)
  File "/home/kix/src/offlineimap3/offlineimap/folder/Base.py", line 828, in copymessageto
    new_uid = dstfolder.savemessage(uid, message, flags, rtime)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kix/src/offlineimap3/offlineimap/folder/IMAP.py", line 728, in savemessage
    raise OfflineImapError(err_msg, OfflineImapError.ERROR.REPO)

WARNING:OfflineImap:
Traceback:
  File "/home/kix/src/offlineimap3/offlineimap/accounts.py", line 298, in syncrunner
    self.__sync()
  File "/home/kix/src/offlineimap3/offlineimap/accounts.py", line 424, in __sync
    syncfolder(self, remotefolder, quick)
  File "/home/kix/src/offlineimap3/offlineimap/accounts.py", line 669, in syncfolder
    localfolder.syncmessagesto(remotefolder, statusfolder)
  File "/home/kix/src/offlineimap3/offlineimap/folder/Base.py", line 1177, in syncmessagesto
    action(dstfolder, statusfolder)
  File "/home/kix/src/offlineimap3/offlineimap/folder/Base.py", line 1004, in __syncmessagesto_copy
    self.copymessageto(uid, dstfolder, statusfolder, register=0)
  File "/home/kix/src/offlineimap3/offlineimap/folder/Base.py", line 828, in copymessageto
    new_uid = dstfolder.savemessage(uid, message, flags, rtime)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kix/src/offlineimap3/offlineimap/folder/IMAP.py", line 728, in savemessage
    raise OfflineImapError(err_msg, OfflineImapError.ERROR.REPO)

Steps to reproduce the error

  • Sync your mail using offlineimap
  • Delete one mail from your inbox in the computer and delete the same mail in the server (with webmail/app)
  • Sync your mail using offlineimap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant