dotnet/reactive · error · ArgumentNullException
new ArgumentNullException(nameof(keySelector))
Error message
new ArgumentNullException(nameof(keySelector))
What it means
GroupBy requires a keySelector (Func<TSource, TKey>) to compute each element's group key. A null selector would make grouping impossible, so the library throws ArgumentNullException(nameof(keySelector)) right after validating the source.
Solutions
- Pass a concrete key selector, e.g. x => x.CategoryId.
- If all elements belong to one group, use a constant selector x => 0 rather than null.
- Null-check the configured selector in your wrapper before delegating to GroupBy.
Example fix
// before var groups = source.GroupBy(null); // after var groups = source.GroupBy(x => x.Key);
Defensive patterns
Strategy: validation
Validate before calling
if (keySelector is null) throw new ArgumentNullException(nameof(keySelector));
Type guard
static bool IsValidKeySelector<TSource, TKey>(Func<TSource, TKey>? k) => k is not null;
Try / catch
try { var groups = source.GroupBy(keySelector); } catch (ArgumentNullException ex) when (ex.ParamName == "keySelector") { keySelector = static _ => default!; } Prevention
- Load key-mapping policies from config with null validation
- Use constant selectors for single-group scenarios instead of null
- Prefer named arguments when calling GroupBy in generic wrappers
When it happens
Trigger: Calling source.GroupBy(null) or passing a null delegate through from a helper/lambda factory — e.g. a key-extraction function resolved from configuration or a method group that failed to bind.
Common situations: Key mapping policy not configured; generic grouping helper that forwards an optional selector defaulting to null; refactoring that left the selector argument empty in a positional call.
Related errors
- new ArgumentNullException(nameof(source))
- ArgumentNullException: keySelector
- Value cannot be null. (Parameter 'observer')
- new ArgumentNullException(nameof(source))
- ArgumentNullException: elementSelector
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/89228d5e75abd855.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs:19
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector)
{
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,View on GitHub (pinned to 94b5d5ab91)