{"record":{"id":"297ff102794b0c68","repo":"dotnet/reactive","slug":"argumentnullexception-observable-standardsequenceoperators","errorCode":null,"errorMessage":"ArgumentNullException","messagePattern":"ArgumentNullException","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.StandardSequenceOperators.cs","lineNumber":197,"sourceCode":"        /// <summary>\n        /// Groups the elements of an observable sequence according to a specified key selector function.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TKey\">The type of the grouping key computed for each element in the source sequence.</typeparam>\n        /// <param name=\"source\">An observable sequence whose elements to group.</param>\n        /// <param name=\"keySelector\">A function to extract the key for each element.</param>\n        /// <returns>A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"keySelector\"/> is null.</exception>\n        public static IObservable<IGroupedObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (keySelector == null)\n            {\n                throw new ArgumentNullException(nameof(keySelector));\n            }\n\n            return s_impl.GroupBy(source, keySelector);\n        }\n\n        /// <summary>\n        /// Groups the elements of an observable sequence according to a specified key selector function and comparer.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TKey\">The type of the grouping key computed for each element in the source sequence.</typeparam>\n        /// <param name=\"source\">An observable sequence whose elements to group.</param>\n        /// <param name=\"keySelector\">A function to extract the key for each element.</param>\n        /// <param name=\"comparer\">An equality comparer to compare keys with.</param>\n        /// <returns>A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"keySelector\"/> or <paramref name=\"comparer\"/> is null.</exception>\n        public static IObservable<IGroupedObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)\n        {\n            if (source == null)","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.StandardSequenceOperators.cs#L179-L215","documentation":"In the single-keySelector GroupBy overload, this throw fires when the keySelector Func<TSource, TKey> is null. GroupBy delegates to s_impl.GroupBy only after all arguments are validated, so the exception surfaces synchronously at the operator call, with Parameter 'keySelector' in the message.","triggerScenarios":"Calling source.GroupBy(null) directly, or passing a method-group/expression variable that was never assigned (e.g. a Func<T,TKey> field defaulting to null).","commonSituations":"Building the key selector dynamically from configuration and the config value is missing; generics-heavy code where a null Func is passed through several layers before reaching GroupBy.","solutions":["Pass a valid key selector lambda, e.g. x => x.Category","Guard the selector before the call and throw a descriptive exception if null","Fix the upstream factory that produced the null Func"],"exampleFix":"// before\nFunc<Order, string> keySel = config.KeySelector; // null when config missing\nvar groups = orders.GroupBy(keySel);\n// after\nvar groups = orders.GroupBy(keySel ?? (o => o.DefaultKey));","handlingStrategy":"validation","validationCode":"if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));\nvar groups = source.GroupBy(keySelector);","typeGuard":"bool HasSelector<T,TKey>(Func<T,TKey> sel) => sel is not null;","tryCatchPattern":"try { var groups = source.GroupBy(keySelector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"keySelector\") { /* selector was null; apply default grouping */ }","preventionTips":["Initialize Func/delegate fields with defaults rather than leaving them null","Validate configured selectors when loading configuration, not at query time","Prefer expression lambdas inline over nullable delegate variables when possible"],"tags":["csharp","rx","null-argument","keyselector"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}