dotnet/wpf · error · InvalidOperationException
SR.InvalidOperation_IComparerFailed
Error message
SR.InvalidOperation_IComparerFailed
What it means
RBTree.Sort wraps QuickSort in a try/catch and rethrows any exception from the comparison as InvalidOperationException(SR.InvalidOperation_IComparerFailed) with the original as InnerException. It means the user-supplied comparer threw (or misbehaved) during sorting of a CollectionView.
Solutions
- Fix the custom IComparer so it handles nulls and mixed types and never throws
- Wrap Compare logic defensively and define a deterministic ordering
- Check the InnerException to find the faulting comparison and the objects involved
Example fix
// before
int IComparer.Compare(object x, object y) => ((Customer)x).Name.CompareTo(((Customer)y).Name); // NRE if Name null
// after
int IComparer.Compare(object x, object y) =>
string.Compare(((Customer)x)?.Name, ((Customer)y)?.Name, StringComparison.OrdinalIgnoreCase); Defensive patterns
Strategy: try-catch
Validate before calling
// smoke-test the comparer over the data before sorting
foreach (var (a,b) in pairs) { int r = comparer.Compare(a,b); if (comparer.Compare(b,a) != -Math.Sign(r) && r!=0) throw new InvalidOperationException("inconsistent comparer"); } Try / catch
try { view.SortDescriptions.Add(sd); view.Refresh(); }
catch (InvalidOperationException ex) when (ex.InnerException != null) { Log.Error("IComparer threw", ex.InnerException); } Prevention
- Make comparers null-safe and total (antisymmetric, transitive)
- Never compare heterogeneous runtypes without checks
- Test comparers against production-like data including nulls
When it happens
Trigger: CollectionView sort with a custom IComparer/SortDescription whose Compare method throws (null dereference, invalid cast, inconsistent comparisons) while RBTree.QuickSort builds the tree.
Common situations: Comparer assuming non-null values on data with nulls, comparing incompatible types after a schema/data change, comparer throwing on removed/refreshed items mid-sort.
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
- SR.Format(SR.ImplementOtherMembersWithSort…
- SR.Format(SR.ImplementOtherMembersWithSort, "Refresh()")
- ArgumentOutOfRangeException
- InvalidEnumArgumentException(direction, (int)direction…
- InvalidOperationException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/73cc39b08d11b625.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/RBTree.cs:125
node.InsertAt(finger.Offset, x, successor, succsucc);
}
LeftChild.IsRed = false;
#if RBTreeFlightRecorder
Verify(size + 1, checkSort);
#endif
}
public void Sort()
{
try
{
QuickSort();
}
catch (Exception e)
{
throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
public void QuickSort()
{
#if RBTreeFlightRecorder
SaveTree();
int size = Count;
#endif
if (Count > 1)
{
RBFinger<T> low = FindIndex(0, false);
RBFinger<T> high = FindIndex(Count, false);
QuickSort3(low, high);
InsertionSortImpl();
}View on GitHub (pinned to 81131a70a4)