jstedfast/MailKit · error · ArgumentException

One or more of the uids is invalid.

Error message

One or more of the uids is invalid.

What it means

UniqueIdSet.ToString() builds a compact IMAP-style range string (e.g. "1:5,8,12:20") by serializing the UIDs it contains. Before serializing it validates every UID in the set; if any UniqueId is invalid (Id == 0, the sentinel for "no uid"), it throws this ArgumentException naming the uids parameter. An invalid UID cannot appear in an IMAP UID set, so the library refuses to produce a malformed sequence set.

Solutions

  1. Filter out invalid UIDs before adding them to the set: skip any uid where !uid.IsValid.
  2. Check the source of each UniqueId (GetUid / GetMessageUid results) and handle UniqueId.Invalid at the call site instead of storing it.
  3. Remove UniqueId.Invalid from an existing set before serializing (rebuild the set from a filtered collection).
  4. Avoid using UniqueId(0) / UniqueId.Invalid as a default or sentinel value in your own collections that later get serialized.

Example fix

// before
var set = new UniqueIdSet ();
foreach (var msg in messages)
    set.Add (folder.GetUid (msg.Index));
var query = set.ToString (); // throws if any uid is invalid

// after
var set = new UniqueIdSet ();
foreach (var msg in messages) {
    var uid = folder.GetUid (msg.Index);
    if (uid.IsValid)
        set.Add (uid);
}
var query = set.ToString ();
Defensive patterns

Strategy: validation

Validate before calling

static bool AllValid (UniqueIdSet set)
{
    for (int i = 0; i < set.Count; i++)
        if (!set[i].IsValid)
            return false;
    return true;
}
// call: if (AllValid (set)) var s = set.ToString ();

Type guard

static bool IsValidUid (UniqueId uid) => uid.IsValid && uid.Id != 0;

Try / catch

try {
    var text = uidSet.ToString ();
} catch (ArgumentException ex) {
    // set contains UniqueId.Invalid; rebuild after filtering
}

Prevention

When it happens

Trigger: Calling ToString() on a UniqueIdSet that contains a UniqueId whose IsValid is false (UniqueId with Id 0). This typically happens when a UniqueId obtained from a failed or no-match message query (e.g. ImapFolder.GetUid(messageIndex) returning UniqueId.Invalid) is added to the set, then ToString() (directly or indirectly via APIs that build UID sequence sets) is called.

Common situations: Developers accumulate UIDs from message fetches where some lookups return UniqueId.Invalid, add them to a UniqueIdSet to build a FETCH or STORE command, and serialize it. Also common after downloading via POP or constructing UniqueId(0) by mistake as a 'default' value.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at MailKit/UniqueIdSet.cs:847

			}

			if (uids is UniqueIdRange range) {
				yield return range.ToString ();
				yield break;
			}

			if (uids is UniqueIdSet set) {
				foreach (var subset in set.EnumerateSerializedSubsets (maxLength))
					yield return subset;
				yield break;
			}

			var builder = new StringBuilder ();
			int index = 0;

			while (index < uids.Count) {
				if (!uids[index].IsValid)
					throw new ArgumentException ("One or more of the uids is invalid.", nameof (uids));

				uint start = uids[index].Id;
				uint end = uids[index].Id;
				int i = index + 1;

				if (i < uids.Count) {
					if (uids[i].Id == end + 1) {
						end = uids[i++].Id;

						while (i < uids.Count && uids[i].Id == end + 1) {
							end++;
							i++;
						}
					} else if (uids[i].Id == end - 1) {
						end = uids[i++].Id;

						while (i < uids.Count && uids[i].Id == end - 1) {
							end--;

View on GitHub (pinned to 9d3859a785)