dotnet/reactive · error · ArgumentNullException

ArgumentNullException: keySelector

Error message

ArgumentNullException: keySelector

What it means

The GroupBy(source, keySelector, elementSelector) overload throws ArgumentNullException when keySelector is null. The key selector determines each element's group key and is required to build the grouping; there is no default, so a null is rejected up front. Fail-fast avoids a null failure only when the first element arrives.

Solutions

  1. Pass a valid Func<TSource,TKey> as keySelector
  2. If the selector is variable, initialize it with a default such as _ => default before use
  3. Guard with ArgumentNullException.ThrowIfNull(keySelector) in your own wrapper first

Example fix

// before
var grouped = source.GroupBy(null, x => x);
// after
Func<Order, int> keySelector = o => o.CustomerId;
var grouped = source.GroupBy(keySelector, x => x);
Defensive patterns

Strategy: validation

Validate before calling

if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));

Type guard

bool IsValidSelector<TSource,TKey>(Func<TSource,TKey> f) => f is not null;

Try / catch

try { var g = source.GroupBy(keySelector, e); } catch (ArgumentNullException ex) when (ex.ParamName == "keySelector") { /* supply default selector and retry */ }

Prevention

When it happens

Trigger: Calling GroupBy with a null second argument, e.g. GroupBy(source, null, x => x), often from a dynamically chosen selector variable that was never assigned.

Common situations: Conditional key selection logic where one branch leaves the Func null; passing a method group whose method is resolved via reflection and came back null; copy-paste where the key selector was accidentally deleted.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs:79

            if (keySelector == null)
                throw new ArgumentNullException(nameof(keySelector));
            if (capacity < 0)
                throw new ArgumentOutOfRangeException(nameof(capacity));
            if (comparer == null)
                throw new ArgumentNullException(nameof(comparer));

            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(
                source,
                (keySelector, capacity, comparer),
                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.capacity, state.comparer)));
        }

        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (keySelector == null)
                throw new ArgumentNullException(nameof(keySelector));
            if (elementSelector == null)
                throw new ArgumentNullException(nameof(elementSelector));

            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TElement>>.From(
                source,
                (keySelector, elementSelector),
                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.elementSelector)));
        }

        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (keySelector == null)
                throw new ArgumentNullException(nameof(keySelector));
            if (elementSelector == null)
                throw new ArgumentNullException(nameof(elementSelector));
            if (comparer == null)

View on GitHub (pinned to 94b5d5ab91)