jstedfast/MailKit · error · InvalidOperationException

If FlagChange and/or AnnotationChange are specified…

Error message

If FlagChange and/or AnnotationChange are specified, MessageNew and MessageExpunge must also be specified.

What it means

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.

Solutions

  1. Add both ImapEvent.MessageNew and ImapEvent.MessageExpunge alongside FlagChange/AnnotationChange in Events
  2. Drop FlagChange/AnnotationChange if paired message events are not desired
  3. Pre-validate the Events list in application code before issuing NOTIFY

Example fix

// before
var group = new ImapEventGroup(ImapMailboxFilter.Selected) {
    Events = { ImapEvent.FlagChange }
};

// after
var group = new ImapEventGroup(ImapMailboxFilter.Selected) {
    Events = { ImapEvent.FlagChange, ImapEvent.MessageNew, ImapEvent.MessageExpunge }
};
Defensive patterns

Strategy: validation

Validate before calling

bool HasRequiredPairs(ImapEventGroup g) {
    bool hasFlagOrAnno = g.Events.Contains(ImapEvent.FlagChange) || g.Events.Contains(ImapEvent.AnnotationChange);
    return !hasFlagOrAnno || (g.Events.Contains(ImapEvent.MessageNew) && g.Events.Contains(ImapEvent.MessageExpunge));
}

Type guard

null

Try / catch

try {
    client.Notify(groups);
} catch (InvalidOperationException ex) when (ex.Message.Contains("FlagChange")) {
    // add MessageNew + MessageExpunge to the group
}

Prevention

When it happens

Trigger: Creating an ImapEventGroup with Events containing ImapEvent.FlagChange (or AnnotationChange) but omitting MessageNew or MessageExpunge, then calling the NOTIFY command.

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15). Data as JSON: /api/errors/d2e1e375761862c4. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/Net/Imap/ImapEventGroup.cs:161

						haveMessageExpunge = true;
					else if (@event == ImapEvent.FlagChange)
						haveFlagChange = true;
					else if (@event == ImapEvent.AnnotationChange)
						haveAnnotationChange = true;

					if (i > 0)
						command.Append (' ');

					@event.Format (engine, command, args, isSelectedFilter);
				}
				command.Append (')');

				// https://tools.ietf.org/html/rfc5465#section-5
				if ((haveMessageNew && !haveMessageExpunge) || (!haveMessageNew && haveMessageExpunge))
					throw new InvalidOperationException ("If MessageNew or MessageExpunge is specified, both must be specified.");

				if ((haveFlagChange || haveAnnotationChange) && (!haveMessageNew || !haveMessageExpunge))
					throw new InvalidOperationException ("If FlagChange and/or AnnotationChange are specified, MessageNew and MessageExpunge must also be specified.");

				notifySelectedNewExpunge = (haveMessageNew || haveMessageExpunge) && MailboxFilter == ImapMailboxFilter.Selected;
			} else {
				command.Append ("NONE");
			}

			command.Append (')');
		}
	}

	/// <summary>
	/// An IMAP mailbox filter for use with the NOTIFY command.
	/// </summary>
	/// <remarks>
	/// An IMAP mailbox filter for use with the NOTIFY command.
	/// </remarks>
	public class ImapMailboxFilter
	{

View on GitHub (pinned to 9d3859a785)