dotnet/reactive · error · ArgumentNullException
ArgumentNullException(nameof(comparer))
Error message
ArgumentNullException(nameof(comparer))
What it means
The comparer overload of ToLookup requires a non-null IEqualityComparer<TKey>. Passing a null comparer throws ArgumentNullException(nameof(comparer)) synchronously; pass EqualityComparer<TKey>.Default for default key comparison.
Solutions
- Use EqualityComparer<TKey>.Default when you want default comparison.
- Verify your comparer is constructed/registered before building the query.
- Drop the comparer argument and use the two-selector overload.
Example fix
// before IEqualityComparer<string> cmp = GetComparer(); // may be null var lookup = src.ToLookup(o => o.Name, o => o, cmp); // after var cmp = GetComparer() ?? EqualityComparer<string>.Default; var lookup = src.ToLookup(o => o.Name, o => o, cmp);
Defensive patterns
Strategy: validation
Validate before calling
var cmp = maybeComparer ?? EqualityComparer<TKey>.Default; if (cmp is null) throw new ArgumentNullException(nameof(comparer));
Type guard
static bool IsValidComparer<TKey>(IEqualityComparer<TKey> c) => c is not null;
Try / catch
try { var lookup = src.ToLookup(keySel, valSel, cmp); }
catch (ArgumentNullException ex) when (ex.ParamName == "comparer") { /* fall back to default comparer */ } Prevention
- Default to EqualityComparer<TKey>.Default for standard key types.
- Verify DI registrations provide the comparer (e.g. validate the container at startup).
- Never expose nullable comparer fields in query-building classes.
When it happens
Trigger: Calling source.ToLookup(keySelector, valueSelector, comparer) with comparer == null, usually because a comparer field was null or the comparer parameter defaulted to null.
Common situations: Injecting custom comparers via DI where registration is missing; conditionally chosen comparers that end up null for a given key type.
Related errors
- comparer
- Value cannot be null. (Parameter 'second')
- Value cannot be null. (Parameter 'sources')
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'selector')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/74defd96fef96246.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/ToLookup.cs:37
if (valueSelector == null)
throw new ArgumentNullException(nameof(valueSelector));
return CreateAsyncObservable<ILookup<TKey, TValue>>.From(
source,
(keySelector, valueSelector),
static (source, state, observer) => source.SubscribeSafeAsync(AsyncObserver.ToLookup(observer, state.keySelector, state.valueSelector)));
}
public static IAsyncObservable<ILookup<TKey, TValue>> ToLookup<TSource, TKey, TValue>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TValue> valueSelector, IEqualityComparer<TKey> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (valueSelector == null)
throw new ArgumentNullException(nameof(valueSelector));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return CreateAsyncObservable<ILookup<TKey, TValue>>.From(
source,
(keySelector, valueSelector, comparer),
static (source, state, observer) => source.SubscribeSafeAsync(AsyncObserver.ToLookup(observer, state.keySelector, state.valueSelector, state.comparer)));
}
public static IAsyncObservable<ILookup<TKey, TValue>> ToLookup<TSource, TKey, TValue>(this IAsyncObservable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, Func<TSource, ValueTask<TValue>> valueSelector)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (valueSelector == null)
throw new ArgumentNullException(nameof(valueSelector));
return CreateAsyncObservable<ILookup<TKey, TValue>>.From(
source,View on GitHub (pinned to 94b5d5ab91)