{"record":{"id":"7f597f8e676dbe36","repo":"dotnet/reactive","slug":"argumentnullexception-nameof-resultselector","errorCode":null,"errorMessage":"ArgumentNullException(nameof(resultSelector))","messagePattern":"ArgumentNullException\\(nameof\\(resultSelector\\)\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs","lineNumber":274,"sourceCode":"        /// <param name=\"resultSelector\">Function to invoke whenever either of the sources produces an element.</param>\n        /// <returns>An observable sequence containing the result of combining elements of both sources using the specified result selector function.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"first\"/> or <paramref name=\"second\"/> or <paramref name=\"resultSelector\"/> is null.</exception>\n        /// <remarks>If a non-empty source completes, its very last value will be used for creating subsequent combinations until all sources terminate.</remarks>\n        public static IObservable<TResult> CombineLatest<TSource1, TSource2, TResult>(this IObservable<TSource1> first, IObservable<TSource2> second, Func<TSource1, TSource2, TResult> resultSelector)\n        {\n            if (first == null)\n            {\n                throw new ArgumentNullException(nameof(first));\n            }\n\n            if (second == null)\n            {\n                throw new ArgumentNullException(nameof(second));\n            }\n\n            if (resultSelector == null)\n            {\n                throw new ArgumentNullException(nameof(resultSelector));\n            }\n\n            return s_impl.CombineLatest(first, second, resultSelector);\n        }\n\n        /// <summary>\n        /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequences.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence, returned by the selector function.</typeparam>\n        /// <param name=\"sources\">Observable sources.</param>\n        /// <param name=\"resultSelector\">Function to invoke whenever any of the sources produces an element. For efficiency, the input list is reused after the selector returns. Either aggregate or copy the values during the function call.</param>\n        /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"sources\"/> or <paramref name=\"resultSelector\"/> is null.</exception>\n        /// <remarks>If a non-empty source completes, its very last value will be used for creating subsequent combinations until all sources terminate.</remarks>\n        public static IObservable<TResult> CombineLatest<TSource, TResult>(this IEnumerable<IObservable<TSource>> sources, Func<IList<TSource>, TResult> resultSelector)\n        {\n            if (sources == null)","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs#L256-L292","documentation":"CombineLatest<TSource1,TSource2,TResult> throws ArgumentNullException when the resultSelector delegate is null (Observable.Multiple.cs:274). Both observables were non-null, so the selector check is the one that fired. Rx requires a real combining function since CombineLatest cannot proceed without it.","triggerScenarios":"Calling first.CombineLatest(second, null), often when the selector is computed dynamically or conditionally assigned.","commonSituations":"Selector stored in a field or injected dependency that was never set; configuration selecting a strategy by name that mapped to null; refactoring where a method group no longer resolves and a null was passed instead.","solutions":["Supply a concrete lambda or method group as the resultSelector.","Fall back to a default selector: first.CombineLatest(second, (a, b) => (a, b)) if combining logic is optional.","If the selector is configurable, validate it is non-null at configuration load time."],"exampleFix":"// before\nFunc<int, string, string> selector = strategy?.Selector; // may be null\nvar combined = a.CombineLatest(b, selector);\n// after\nvar combined = a.CombineLatest(b, strategy?.Selector ?? ((x, y) => $\"{x}:{y}\"));","handlingStrategy":"validation","validationCode":"if (resultSelector == null) throw new InvalidOperationException(\"resultSelector required\"); // or: resultSelector ??= ((a, b) => (a, b));","typeGuard":"bool HasSelector(Func<TSource1, TSource2, TResult>? selector) => selector is not null;","tryCatchPattern":"try { var result = first.CombineLatest(second, resultSelector); } catch (ArgumentNullException ex) when (ex.ParamName == \"resultSelector\") { /* use a default combining function */ }","preventionTips":["Use method groups or lambdas inline rather than nullable delegate fields.","Validate configured selectors at startup.","Provide identity/pairing default selectors for optional combining logic."],"tags":["rx","argument-null","delegate"],"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"}