jstedfast/MailKit · error · InvalidOperationException

If MessageNew or MessageExpunge is specified, both must be…

Error message

If MessageNew or MessageExpunge is specified, both must be specified.

What it means

Per RFC 5465 section 5, within a NOTIFY event group the MessageNew and MessageExpunge events are paired: if you specify one you must specify the other. ImapEventGroup.Format() enforces this when building the NOTIFY command and throws InvalidOperationException otherwise.

Solutions

  1. Add both ImapEvent.MessageNew and ImapEvent.MessageExpunge to the Events list
  2. If you only want new-message notifications without expunges, still include MessageExpunge as required by the spec
  3. Filter events out entirely (Events = empty -> NONE) if you don't need the pair

Example fix

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

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

Strategy: validation

Validate before calling

bool HasPairedMessageEvents(ImapEventGroup g) =>
    g.Events.Count == 0 ||
    (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("MessageNew or MessageExpunge")) {
    // fix event list to include both
}

Prevention

When it happens

Trigger: Building an ImapEventGroup whose Events contain ImapEvent.MessageNew but not ImapEvent.MessageExpunge (or vice versa) with a non-empty event list, then issuing NOTIFY.

Common situations: Developers add MessageNew because they only care about new mail, unaware the IMAP NOTIFY spec requires the pair so the server can send consistent expunge information for QRESYNC/ESELECT.

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/b33e79aaa02468d6. Report an issue: GitHub.

Appendix: source

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

					if (@event is ImapEvent.MessageNew)
						haveMessageNew = true;
					else if (@event == ImapEvent.MessageExpunge)
						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.

View on GitHub (pinned to 9d3859a785)