{"record":{"id":"d7b01e03db977602","repo":"dotnet/reactive","slug":"argumentnullexception-keyselector","errorCode":null,"errorMessage":"ArgumentNullException: keySelector","messagePattern":"ArgumentNullException: keySelector","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs","lineNumber":79,"sourceCode":"            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (capacity < 0)\n                throw new ArgumentOutOfRangeException(nameof(capacity));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(\n                source,\n                (keySelector, capacity, comparer),\n                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.capacity, state.comparer)));\n        }\n\n        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (elementSelector == null)\n                throw new ArgumentNullException(nameof(elementSelector));\n\n            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TElement>>.From(\n                source,\n                (keySelector, elementSelector),\n                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.elementSelector)));\n        }\n\n        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)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (elementSelector == null)\n                throw new ArgumentNullException(nameof(elementSelector));\n            if (comparer == null)","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs#L61-L97","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a valid Func<TSource,TKey> as keySelector","If the selector is variable, initialize it with a default such as _ => default before use","Guard with ArgumentNullException.ThrowIfNull(keySelector) in your own wrapper first"],"exampleFix":"// before\nvar grouped = source.GroupBy(null, x => x);\n// after\nFunc<Order, int> keySelector = o => o.CustomerId;\nvar grouped = source.GroupBy(keySelector, x => x);","handlingStrategy":"validation","validationCode":"if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));","typeGuard":"bool IsValidSelector<TSource,TKey>(Func<TSource,TKey> f) => f is not null;","tryCatchPattern":"try { var g = source.GroupBy(keySelector, e); } catch (ArgumentNullException ex) when (ex.ParamName == \"keySelector\") { /* supply default selector and retry */ }","preventionTips":["Initialize Func variables inline with their definition; avoid 'Func<T,K> sel;' declared-then-assigned patterns","Give conditional selector branches a default case","Prefer method groups (o => o.Key) over nullable delegate fields"],"tags":["argument-null","key-selector","groupby","validation"],"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"}