dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'comparer')

Error message

Value cannot be null. (Parameter 'comparer')

What it means

The two-argument Min overload requires a non-null IComparer<TSource>. The library throws ArgumentNullException with Parameter 'comparer' when null is supplied, because every element comparison during aggregation depends on it. Pass Comparer<T>.Default (or use the single-argument overload) when no custom comparer is needed.

Solutions

  1. Pass a concrete comparer or Comparer<TSource>.Default instead of null
  2. Use the single-argument Min(source) overload which defaults to Comparer<TSource>.Default
  3. Validate the comparer at your API boundary before forwarding it

Example fix

// before
var result = AsyncObservable.Min(source, null);
// after
var result = AsyncObservable.Min(source, Comparer<MyType>.Default);
Defensive patterns

Strategy: validation

Validate before calling

if (source == null) throw new ArgumentNullException(nameof(source));
if (comparer == null) comparer = Comparer<TSource>.Default;

Type guard

bool IsValidComparer<T>(IComparer<T> c) => c is not null;

Try / catch

try { var result = AsyncObservable.Min(source, comparer); }
catch (ArgumentNullException ex) when (ex.ParamName == "comparer") { /* pass Comparer<T>.Default */ }

Prevention

When it happens

Trigger: Calling Min(source, comparer) with comparer = null, e.g. a comparer parameter forwarded from a caller that passed null.

Common situations: Wrapping APIs that accept an optional IComparer<T> and forwarding it unvalidated to Min; returning null from a comparer-provider factory; forgetting Comparer<T>.Default in generic helper code.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/d194b9422eb85f93. Report an issue: GitHub.

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Min.cs:25

namespace System.Reactive.Linq
{
    public partial class AsyncObservable
    {
        public static IAsyncObservable<TSource> Min<TSource>(IAsyncObservable<TSource> source)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

            return Create(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Min(observer)));
        }

        public static IAsyncObservable<TSource> Min<TSource>(IAsyncObservable<TSource> source, IComparer<TSource> comparer)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (comparer == null)
                throw new ArgumentNullException(nameof(comparer));

            return CreateAsyncObservable<TSource>.From(
                source,
                comparer,
                static (source, comparer, observer) => source.SubscribeSafeAsync(AsyncObserver.Min(observer, comparer)));
        }
    }

    public partial class AsyncObserver
    {
        public static IAsyncObserver<TSource> Min<TSource>(IAsyncObserver<TSource> observer)
        {
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));

            return Min(observer, Comparer<TSource>.Default);
        }

View on GitHub (pinned to 94b5d5ab91)