dotnet/reactive · error · ArgumentNullException
new ArgumentNullException(nameof(comparer))
Error message
new ArgumentNullException(nameof(comparer))
What it means
The three-argument GroupBy(source, keySelector, comparer) throws ArgumentNullException when comparer is null. A non-null IEqualityComparer<TKey> is required to route elements into groups; unlike plain LINQ-to-Objects, this overload does not fall back to EqualityComparer<TKey>.Default. Validation is performed eagerly at call time.
Solutions
- Pass a non-null IEqualityComparer<TKey>, e.g. EqualityComparer<TKey>.Default if default semantics are desired.
- Fix the comparer factory/registration so it never returns null.
- Coalesce: comparer ?? EqualityComparer<TKey>.Default before the call.
Example fix
// before var groups = source.GroupBy(x => x.Key, resolver.GetComparer<string>()); // may be null // after var groups = source.GroupBy(x => x.Key, resolver.GetComparer<string>() ?? EqualityComparer<string>.Default);
Defensive patterns
Strategy: validation
Validate before calling
if (comparer is null) comparer = EqualityComparer<TKey>.Default;
Type guard
static bool HasComparer<TKey>(IEqualityComparer<TKey> c) => c is not null;
Try / catch
try { var groups = source.GroupBy(keySelector, comparer); }
catch (ArgumentNullException ex) when (ex.ParamName == "comparer") { log.LogError(ex, "GroupBy comparer was null"); throw; } Prevention
- Coalesce comparer ?? EqualityComparer<TKey>.Default at call sites.
- Verify DI registrations for custom comparers at container build time.
- Prefer passing EqualityComparer<TKey>.Default explicitly over null.
When it happens
Trigger: Calling GroupBy(source, keySelector, null) — usually a comparer resolved from configuration, DI container, or a lookup that returned null.
Common situations: DI-registered comparers missing from the container; comparer selected conditionally with no default branch; passing a custom comparer class instance that a factory failed to create.
Related errors
- Value cannot be null. (Parameter 'func')
- Value cannot be null. (Parameter 'resultSelector')
- ArgumentNullException: comparer
- Value cannot be null. (Parameter 'selector')
- Value cannot be null. (Parameter 'sources')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/bfbaa7dc39ab554a.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs:34
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(
source,
keySelector,
static (source, keySelector, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, keySelector)));
}
public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(
source,
(keySelector, comparer),
static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.comparer)));
}
public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, int capacity)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (capacity < 0)
throw new ArgumentOutOfRangeException(nameof(capacity));
return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(
source,View on GitHub (pinned to 94b5d5ab91)