dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'comparer')
Error message
Value cannot be null. (Parameter 'comparer')
What it means
AsyncObservable.Max<TSource>(source, IComparer<TSource>) throws ArgumentNullException('comparer') when the comparer argument is null. Unlike the simple overload, this overload requires an explicit IComparer<TSource>; passing null defeats the comparison logic so the library fails fast instead of silently falling back.
Solutions
- Pass Comparer<T>.Default if you want default comparison instead of null.
- Assign a concrete comparer such as Comparer<int>.Create((a,b) => a.CompareTo(b)) or a custom class implementing IComparer<T>.
- Coalesce at the call site: comparer ?? Comparer<T>.Default.
Example fix
// before var max = AsyncObservable.Max(source, comparer); // comparer is null // after var max = AsyncObservable.Max(source, comparer ?? Comparer<int>.Default);
Defensive patterns
Strategy: validation
Validate before calling
if (comparer is null) comparer = Comparer<TSource>.Default; // then call Max(source, comparer)
Type guard
static bool HasComparer<TSource>(IComparer<TSource>? c) => c is not null;
Try / catch
try { var max = AsyncObservable.Max(source, comparer); }
catch (ArgumentNullException ex) when (ex.ParamName == "comparer") { comparer = Comparer<TSource>.Default; /* retry */ } Prevention
- Never pass null where the API expects IComparer<T>; use Comparer<T>.Default
- Centralize comparer selection in one factory that always returns non-null
- Guard config-driven comparer lookups with a fallback to the default comparer
When it happens
Trigger: Calling AsyncObservable.Max(source, null) — e.g. a comparer field/property that was never assigned, a config-selected comparer that resolved to null, or passing null intending to get the default comparer.
Common situations: Migrating code from Comparer-based APIs where null meant 'use default'; conditional comparer selection (e.g. by culture) where the branch didn't assign; reflection or DI lookups that returned null.
Related errors
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'observer')
- observer
- Value cannot be null. (Parameter 'comparer')
- Value cannot be null. (Parameter 'onCompletedAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/19920fe017f5b248.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Max.cs:25
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Max<TSource>(IAsyncObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return Create(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Max(observer)));
}
public static IAsyncObservable<TSource> Max<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.Max(observer, comparer)));
}
}
public partial class AsyncObserver
{
public static IAsyncObserver<TSource> Max<TSource>(IAsyncObserver<TSource> observer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
return Max(observer, Comparer<TSource>.Default);
}
View on GitHub (pinned to 94b5d5ab91)