{"record":{"id":"58434b0b309728d8","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-keyselector-observable","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'keySelector')","messagePattern":"Value cannot be null\\. \\(Parameter 'keySelector'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs","lineNumber":1582,"sourceCode":"        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TKey\">The type of the key computed for each element in the source sequence.</typeparam>\n        /// <param name=\"source\">An observable sequence to get the maximum elements for.</param>\n        /// <param name=\"keySelector\">Key selector function.</param>\n        /// <param name=\"comparer\">Comparer used to compare key values.</param>\n        /// <returns>An observable sequence containing a list of zero or more elements that have a maximum key value.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"keySelector\"/> or <paramref name=\"comparer\"/> is null.</exception>\n        /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>\n        public static IObservable<IList<TSource>> MaxBy<TSource, TKey>(this IObservable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)\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            if (comparer == null)\n            {\n                throw new ArgumentNullException(nameof(comparer));\n            }\n\n            return s_impl.MaxBy(source, keySelector, comparer);\n        }\n\n        #endregion\n\n        #region + Min +\n\n        /// <summary>\n        /// Returns the minimum element in an observable sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>","sourceCodeStart":1564,"sourceCodeEnd":1600,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs#L1564-L1600","documentation":"The comparer overload of Observable.MaxBy throws ArgumentNullException when the keySelector delegate is null. As with all Rx operators, validation happens synchronously at call time via ArgumentNullException(nameof(keySelector)). keySelector defines the key used with the supplied IComparer<TKey> to rank elements.","triggerScenarios":"Calling Observable.MaxBy(source, null, comparer) — the three-argument overload at Observable.Aggregates.cs:1582 with a null keySelector while supplying a comparer.","commonSituations":"Resolver/DI container returning a null delegate for a registered key-extraction function; a generic helper method whose keySelector parameter was forwarded as null; a nullable Func field not yet initialized at call time.","solutions":["Pass a concrete key-selection lambda, e.g. source.MaxBy(x => x.Age, comparer).","Guard the delegate before the call: if (keySelector == null) throw new InvalidOperationException(\"keySelector required\").","Correct the registration/factory that was supposed to produce the keySelector delegate."],"exampleFix":"// before\nobs.MaxBy(keyExtractor, myComparer); // keyExtractor is null\n// after\nobs.MaxBy(item => item.Key, myComparer);","handlingStrategy":"validation","validationCode":"if (source == null || keySelector == null || comparer == null)\n    throw new ArgumentException(\"MaxBy requires non-null source, keySelector, and comparer\");\nvar r = source.MaxBy(keySelector, comparer);","typeGuard":"bool ValidForMaxBy<T, TKey>(IObservable<T> s, Func<T, TKey> sel) => s is not null && sel is not null;","tryCatchPattern":"try { var r = source.MaxBy(keySelector, comparer); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"keySelector\") { /* provide fallback selector */ }","preventionTips":["When forwarding parameters through generic helper methods, validate them at the boundary.","Verify DI/resolver registrations actually produce non-null delegates.","Prefer inline lambdas over nullable delegate variables for key extraction."],"tags":["csharp","rx","argument-validation","null-reference"],"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"}