jstedfast/MailKit · error · ArgumentException

No sort order provided.

Error message

No sort order provided.

What it means

MessageThreader.Thread throws this ArgumentException when the orderBy list of OrderBy clauses is non-null but empty. Threading requires at least one sort criterion to order messages within threads, so an empty collection is rejected up front.

Solutions

  1. Pass at least one OrderBy value, e.g. new List<OrderBy> { OrderBy.Date }
  2. If the list is built dynamically, validate Count > 0 before calling Thread and choose a sensible default sort
  3. Check that config/serialization of the sort preferences actually produced entries

Example fix

// before
var orderBy = new List<OrderBy>();
var tree = threader.Thread(messages, ThreadingAlgorithm.References, orderBy);
// after
var orderBy = new List<OrderBy> { OrderBy.Date, OrderBy.Subject };
var tree = threader.Thread(messages, ThreadingAlgorithm.References, orderBy);
Defensive patterns

Strategy: validation

Validate before calling

if (orderBy == null || orderBy.Count == 0)
	orderBy = new List<OrderBy> { OrderBy.Date }; // or throw earlier with context

Type guard

bool HasSortOrder(IList<OrderBy> orderBy) => orderBy != null && orderBy.Count > 0;

Try / catch

try {
	tree = threader.Thread(messages, algorithm, orderBy);
} catch (ArgumentException ex) when (ex.ParamName == "orderBy") {
	// fall back to a default sort or skip threading
}

Prevention

When it happens

Trigger: Calling MessageThreader.Thread(messages, algorithm, orderBy) with a valid (non-null) but zero-element IList<OrderBy>, e.g. `new List<OrderBy>()` or a filtered list that ended up empty.

Common situations: Building the sort-order list dynamically from user preferences or config where no sort keys were selected; copy-pasting a Thread call from sample code and deleting the OrderBy items; deserializing sort settings from an empty JSON array.

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


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

Appendix: source

Thrown at MailKit/MessageThreader.cs:452

		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="algorithm"/> is not a valid threading algorithm.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="messages"/> contains one or more items that is missing information needed for threading or sorting.</para>
		/// <para>-or-</para>
		/// <para><paramref name="orderBy"/> is an empty list.</para>
		/// </exception>
		public static IList<MessageThread> Thread (this IEnumerable<IMessageSummary> messages, ThreadingAlgorithm algorithm, IList<OrderBy> orderBy)
		{
			if (messages == null)
				throw new ArgumentNullException (nameof (messages));

			if (orderBy == null)
				throw new ArgumentNullException (nameof (orderBy));

			if (orderBy.Count == 0)
				throw new ArgumentException ("No sort order provided.", nameof (orderBy));

			switch (algorithm) {
			case ThreadingAlgorithm.OrderedSubject: return ThreadBySubject (messages, orderBy);
			case ThreadingAlgorithm.References: return ThreadByReferences (messages, orderBy);
			default: throw new ArgumentOutOfRangeException (nameof (algorithm));
			}
		}

		static bool IsForward (string subject, int index)
		{
			return (subject[index] == 'F' || subject[index] == 'f') &&
				(subject[index + 1] == 'W' || subject[index + 1] == 'w') &&
				(subject[index + 2] == 'D' || subject[index + 2] == 'd') &&
				subject[index + 3] == ':';
		}

		static bool IsReply (string subject, int index)
		{

View on GitHub (pinned to 9d3859a785)