{"record":{"id":"d2e1e375761862c4","repo":"jstedfast/MailKit","slug":"if-flagchange-and-or-annotationchange-are-specified","errorCode":null,"errorMessage":"If FlagChange and/or AnnotationChange are specified, MessageNew and MessageExpunge must also be specified.","messagePattern":"If FlagChange and/or AnnotationChange are specified, MessageNew and MessageExpunge must also be specified\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"MailKit/Net/Imap/ImapEventGroup.cs","lineNumber":161,"sourceCode":"\t\t\t\t\t\thaveMessageExpunge = true;\n\t\t\t\t\telse if (@event == ImapEvent.FlagChange)\n\t\t\t\t\t\thaveFlagChange = true;\n\t\t\t\t\telse if (@event == ImapEvent.AnnotationChange)\n\t\t\t\t\t\thaveAnnotationChange = true;\n\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\tcommand.Append (' ');\n\n\t\t\t\t\t@event.Format (engine, command, args, isSelectedFilter);\n\t\t\t\t}\n\t\t\t\tcommand.Append (')');\n\n\t\t\t\t// https://tools.ietf.org/html/rfc5465#section-5\n\t\t\t\tif ((haveMessageNew && !haveMessageExpunge) || (!haveMessageNew && haveMessageExpunge))\n\t\t\t\t\tthrow new InvalidOperationException (\"If MessageNew or MessageExpunge is specified, both must be specified.\");\n\n\t\t\t\tif ((haveFlagChange || haveAnnotationChange) && (!haveMessageNew || !haveMessageExpunge))\n\t\t\t\t\tthrow new InvalidOperationException (\"If FlagChange and/or AnnotationChange are specified, MessageNew and MessageExpunge must also be specified.\");\n\n\t\t\t\tnotifySelectedNewExpunge = (haveMessageNew || haveMessageExpunge) && MailboxFilter == ImapMailboxFilter.Selected;\n\t\t\t} else {\n\t\t\t\tcommand.Append (\"NONE\");\n\t\t\t}\n\n\t\t\tcommand.Append (')');\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// An IMAP mailbox filter for use with the NOTIFY command.\n\t/// </summary>\n\t/// <remarks>\n\t/// An IMAP mailbox filter for use with the NOTIFY command.\n\t/// </remarks>\n\tpublic class ImapMailboxFilter\n\t{","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/Net/Imap/ImapEventGroup.cs#L143-L179","documentation":"RFC 5465 requires that FlagChange and AnnotationChange events in a NOTIFY event group appear only together with both MessageNew and MessageExpunge. Format() throws InvalidOperationException when FlagChange and/or AnnotationChange are present but MessageNew or MessageExpunge is missing.","triggerScenarios":"Creating an ImapEventGroup with Events containing ImapEvent.FlagChange (or AnnotationChange) but omitting MessageNew or MessageExpunge, then calling the NOTIFY command.","commonSituations":"Developers who want flag-change notifications add only FlagChange, not realizing the spec anchors flag/annotation changes to the message new/expunge pair for selected-mailbox consistency.","solutions":["Add both ImapEvent.MessageNew and ImapEvent.MessageExpunge alongside FlagChange/AnnotationChange in Events","Drop FlagChange/AnnotationChange if paired message events are not desired","Pre-validate the Events list in application code before issuing NOTIFY"],"exampleFix":"// before\nvar group = new ImapEventGroup(ImapMailboxFilter.Selected) {\n    Events = { ImapEvent.FlagChange }\n};\n\n// after\nvar group = new ImapEventGroup(ImapMailboxFilter.Selected) {\n    Events = { ImapEvent.FlagChange, ImapEvent.MessageNew, ImapEvent.MessageExpunge }\n};","handlingStrategy":"validation","validationCode":"bool HasRequiredPairs(ImapEventGroup g) {\n    bool hasFlagOrAnno = g.Events.Contains(ImapEvent.FlagChange) || g.Events.Contains(ImapEvent.AnnotationChange);\n    return !hasFlagOrAnno || (g.Events.Contains(ImapEvent.MessageNew) && g.Events.Contains(ImapEvent.MessageExpunge));\n}","typeGuard":"null","tryCatchPattern":"try {\n    client.Notify(groups);\n} catch (InvalidOperationException ex) when (ex.Message.Contains(\"FlagChange\")) {\n    // add MessageNew + MessageExpunge to the group\n}","preventionTips":["Treat FlagChange/AnnotationChange as requiring the message event pair","Centralize event-group construction in one validated factory","Write tests mirroring RFC 5465 section 5 constraints"],"tags":["imap","notify","rfc5465","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"9d3859a7855e3e17582c07fd01972b8e262bf176","analyzedAt":"2026-09-15T15:46:11.592Z","contentChangedAt":"2026-09-15T15:46:11.592Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}