{"record":{"id":"665254abaea4a26f","repo":"dotnet/reactive","slug":"keyselector-groupby","errorCode":null,"errorMessage":"keySelector","messagePattern":"keySelector","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs","lineNumber":412,"sourceCode":"                throw new ArgumentNullException(nameof(keySelector));\n            if (elementSelector == null)\n                throw new ArgumentNullException(nameof(elementSelector));\n            if (capacity < 0)\n                throw new ArgumentOutOfRangeException(nameof(capacity));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return GroupBy<TSource, TKey, TElement>(observer, subscription, x => new ValueTask<TKey>(keySelector(x)), x => new ValueTask<TElement>(elementSelector(x)), capacity, comparer);\n        }\n\n        public static (IAsyncObserver<TSource>, IAsyncDisposable) GroupBy<TSource, TKey>(IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> observer, IAsyncDisposable subscription, Func<TSource, ValueTask<TKey>> keySelector)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (subscription == null)\n                throw new ArgumentNullException(nameof(subscription));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n\n            return GroupBy(observer, subscription, keySelector, int.MaxValue, EqualityComparer<TKey>.Default);\n        }\n\n        public static (IAsyncObserver<TSource>, IAsyncDisposable) GroupBy<TSource, TKey>(IAsyncObserver<IGroupedAsyncObservable<TKey, TSource>> observer, IAsyncDisposable subscription, Func<TSource, ValueTask<TKey>> keySelector, IEqualityComparer<TKey> comparer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (subscription == null)\n                throw new ArgumentNullException(nameof(subscription));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return GroupBy(observer, subscription, keySelector, int.MaxValue, comparer);\n        }\n","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs#L394-L430","documentation":"GroupBy throws ArgumentNullException because the keySelector Func<TSource, ValueTask<TKey>> is null. The key selector is the essence of grouping — without it no groups can be formed — so it is validated up front and the call aborts.","triggerScenarios":"Calling GroupBy<TSource,TKey>(observer, subscription, null) — a null keySelector literal or a Func variable that is null (e.g. an optional selector parameter not supplied).","commonSituations":"Passing a selector stored in a nullable delegate field that was never assigned; conditional query building where the selector expression was skipped; calling GroupBy from generic wrapper code that forwards a null selector.","solutions":["Supply a key selector lambda, e.g. x => x.CustomerId, wrapped in a ValueTask if needed.","If the selector is optional, default to x => default before calling GroupBy.","Null-check the delegate at the call site before entering the operator pipeline.","Make sure the generic type arguments TKey match the selector's return type so the right overload is bound."],"exampleFix":"// before\nvar grp = GroupBy<TSource, TKey>(observer, subscription, keySelector); // keySelector is null\n// after\nFunc<TSource, ValueTask<TKey>> keySelector = async x => (await x.GetKeyAsync());\nvar grp = GroupBy<TSource, TKey>(observer, subscription, keySelector);","handlingStrategy":"validation","validationCode":"if (keySelector == null) throw new InvalidOperationException(\"keySelector is required for GroupBy\");\nvar grp = GroupBy<TSource, TKey>(observer, subscription, keySelector);","typeGuard":"bool IsValidSelector<TSource, TKey>(Func<TSource, ValueTask<TKey>> selector) => selector is not null;","tryCatchPattern":"try { var grp = GroupBy<TSource, TKey>(observer, subscription, keySelector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"keySelector\") { /* supply a selector */ }","preventionTips":["Pass selectors as inline lambdas rather than nullable delegate fields when possible.","Coalesce optional selectors: keySelector ?? (x => new ValueTask<TKey>(default)).","Enable nullable reference types to catch uninitialized delegate fields."],"tags":["argument-null","reactive-extensions","groupby","csharp"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}