{"record":{"id":"99daac9c06cdec6c","repo":"RocketChat/Rocket.Chat","slug":"mark-deleted-error","errorCode":null,"errorMessage":"Mark deleted error","messagePattern":"Mark deleted error","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/meteor/server/email/IMAPInterceptor.ts","lineNumber":193,"sourceCode":"\t\t});\n\t}\n\n\timapFetch(emailIds: number[]): Promise<number[]> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst out: number[] = [];\n\t\t\tconst messagecb = (msg: ImapMessage, seqno: number) => {\n\t\t\t\tout.push(seqno);\n\t\t\t\tconst bodycb = (stream: NodeJS.ReadableStream, _info: ImapMessageBodyInfo): void => {\n\t\t\t\t\tsimpleParser(new Readable().wrap(stream), (_err, email) => {\n\t\t\t\t\t\tif (this.options.rejectBeforeTS && email.date && email.date < this.options.rejectBeforeTS) {\n\t\t\t\t\t\t\tlogger.error({ msg: 'Rejecting email on inbox', user: this.config.user, subject: email.subject });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.emit('email', email);\n\t\t\t\t\t\tif (this.options.deleteAfterRead) {\n\t\t\t\t\t\t\tthis.imap.seq.addFlags(email, 'Deleted', (err) => {\n\t\t\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\t\t\tlogger.warn({ msg: 'Mark deleted error', err });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t\tmsg.once('body', bodycb);\n\t\t\t};\n\t\t\tconst errorcb = (err: Error): void => {\n\t\t\t\tlogger.warn({ msg: 'Fetch error', err });\n\t\t\t\treject(err);\n\t\t\t};\n\t\t\tconst endcb = (): void => {\n\t\t\t\tresolve(out);\n\t\t\t};\n\t\t\tconst fetch = this.imap.fetch(emailIds, {\n\t\t\t\tbodies: ['HEADER', 'TEXT', ''],\n\t\t\t\tstruct: true,\n\t\t\t\tmarkSeen: this.options.markSeen,","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/email/IMAPInterceptor.ts#L175-L211","documentation":"In the inbound-email IMAP interceptor with deleteAfterRead enabled, after an email is parsed it is flagged \\Deleted via imap.seq.addFlags; the IMAP server rejected that STORE operation and the failure is only logged. The message therefore stays in the mailbox and will be fetched and re-emitted again on the next poll. Note the call passes the parsed email object rather than the seqno available in the enclosing messagecb — depending on the imap library version this itself can make the flag call fail for every message.","triggerScenarios":"IMAP connection dropped between the fetch and the flag operation; mailbox opened read-only or the account lacks permission to set flags; server-side STORE failure (quota/ACL); passing an invalid message source to seq.addFlags (parsed email object instead of sequence number).","commonSituations":"Gmail/Office365 throttling long-lived connections; service mailboxes without write/delete ACL; flaky networks causing reconnect mid-batch; the same emails re-processed every poll because they never get flagged deleted.","solutions":["Check the logged err text: 'Mailbox is read-only' means permissions; connection errors mean stability","Grant the IMAP account write/delete permission on the mailbox","If the warn fires for every message, verify the addFlags argument against your imap library — seq.addFlags expects the sequence number (seqno), not the parsed email","Keep batches small and let the interceptor reconnect before flagging"],"exampleFix":"// before: parsed email object passed to the seq-based flag API\nthis.imap.seq.addFlags(email, 'Deleted', (err) => { ... });\n// after: use the sequence number captured in messagecb\nthis.imap.seq.addFlags(seqno, 'Deleted', (err) => { ... });","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"this.imap.seq.addFlags(seqno, 'Deleted', (err) => {\n\tif (err) {\n\t\t// keep the message id so the next poll retries the delete instead of re-emitting forever\n\t\tlogger.warn({ msg: 'Mark deleted error', seqno, err });\n\t}\n});","preventionTips":["Use a dedicated IMAP account with write/delete ACL on the mailbox","Verify the flag call uses the sequence number, not the parsed email object","Idempotently track processed message ids so a failed flag does not duplicate inbound emails"],"tags":["imap","email","inbound-email","node-imap"],"backgroundTag":"imap-flag-store-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}