jstedfast/MailKit · error · ArgumentException
Must supply at least one folder.
Error message
Must supply at least one folder.
What it means
ImapEventGroup.Mailboxes.CreateEventGroup-style constructor requires a non-empty list of folders; passing an empty IList<IMailFolder> throws ArgumentException("Must supply at least one folder."). A mailboxes event group with zero folders would produce a meaningless NOTIFY filter.
Solutions
- Check folders.Count > 0 before calling Mailboxes and skip or short-circuit the NOTIFY setup if empty
- Fall back to ImapEventGroup.Personal or Selected when no specific folders are available
- Fix the upstream query that produced the empty folder list if it should have returned folders
Example fix
// before
var group = ImapEventGroup.Mailboxes("notify", matchedFolders);
// after
if (matchedFolders.Count == 0) {
var group = ImapEventGroup.Personal();
} else {
var group = ImapEventGroup.Mailboxes("notify", matchedFolders);
} Defensive patterns
Strategy: validation
Validate before calling
if (folders == null || folders.Count == 0)
throw new ArgumentException("Must supply at least one folder before building a Mailboxes event group."); Type guard
bool HasFolders(IList<IMailFolder> folders) => folders is { Count: > 0 }; Try / catch
try {
var group = ImapEventGroup.Mailboxes(name, folders);
} catch (ArgumentException ex) when (ex.ParamName == "folders") {
// fall back to Personal/Selected group or skip NOTIFY
} Prevention
- Guard folder lists before constructing groups
- Log when a folder query returns empty so the NOTIFY setup can be skipped
- Validate derived configuration before applying it to the client
When it happens
Trigger: Calling ImapEventGroup.Mailboxes (the static factory/constructor for a folders-based group) with an empty List<IMailFolder>, e.g. when a folder-search produced no results before constructing the group.
Common situations: Computing the folder list dynamically (e.g. from a UI selection or GetFolders result) and passing it unfiltered; empty search results silently flowing into the NOTIFY setup.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- All folders must be ImapFolders.
- Annotation entry paths must not end with '/'.
- Annotation entry paths must not end with '.'.
- Cannot rename a folder using itself as the new parent…
- Cannot search for an empty set of unique identifiers.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/f749393bd80cc5ac.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapEventGroup.cs:309
/// </remarks>
/// <param name="name">The name of the mailbox filter.</param>
/// <param name="folders">The list of folders to watch for events.</param>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="folders"/> is <see langword="null" />.
/// </exception>
/// <exception cref="System.ArgumentException">
/// <para>The list of <paramref name="folders"/> is empty.</para>
/// <para>-or-</para>
/// <para>The list of <paramref name="folders"/> contains folders that are not of
/// type <see cref="ImapFolder"/>.</para>
/// </exception>
internal Mailboxes (string name, IList<IMailFolder> folders) : base (name)
{
if (folders == null)
throw new ArgumentNullException (nameof (folders));
if (folders.Count == 0)
throw new ArgumentException ("Must supply at least one folder.", nameof (folders));
this.folders = new ImapFolder[folders.Count];
for (int i = 0; i < folders.Count; i++) {
if (folders[i] is not ImapFolder folder)
throw new ArgumentException ("All folders must be ImapFolders.", nameof (folders));
this.folders[i] = folder;
}
}
/// <summary>
/// Format the IMAP NOTIFY command for this particular IMAP mailbox filter.
/// </summary>
/// <remarks>
/// Formats the IMAP NOTIFY command for this particular IMAP mailbox filter.
/// </remarks>
/// <param name="engine">The IMAP engine.</param>
/// <param name="command">The IMAP command builder.</param>View on GitHub (pinned to 9d3859a785)