{"record":{"id":"b6126744fd0de635","repo":"dotnet/reactive","slug":"argumentnullexception-nameof-second","errorCode":null,"errorMessage":"ArgumentNullException(nameof(second))","messagePattern":"ArgumentNullException\\(nameof\\(second\\)\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs","lineNumber":269,"sourceCode":"        /// <typeparam name=\"TSource1\">The type of the elements in the first source sequence.</typeparam>\n        /// <typeparam name=\"TSource2\">The type of the elements in the second source sequence.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence, returned by the selector function.</typeparam>\n        /// <param name=\"first\">First observable source.</param>\n        /// <param name=\"second\">Second observable source.</param>\n        /// <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>","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs#L251-L287","documentation":"CombineLatest<TSource1,TSource2,TResult> throws ArgumentNullException when the second observable is null (Observable.Multiple.cs:269). The first argument was non-null (its check at line 264 passed), so validation proceeded to the second parameter. The throw is synchronous, before any subscription occurs.","triggerScenarios":"Calling first.CombineLatest(null, selector) or Observable.CombineLatest(first, null, selector) with a null second IObservable.","commonSituations":"Second stream comes from an optional feature toggle or cache lookup that returned null; a Subject field not yet constructed; API migration where an optional source was passed as null instead of Observable.Empty.","solutions":["Pass a real (possibly empty) observable instead of null: Observable.Empty<TSource2>().","Coalesce before combining: (second ?? Observable.Empty<TSource2>()).","Fix the source factory so it always returns an observable, never null."],"exampleFix":"// before\nvar combined = clicks.CombineLatest(GetValueStream(), (c, v) => Format(c, v));\n// GetValueStream() can return null\n// after\nvar valueStream = GetValueStream() ?? Observable.Empty<Value>();\nvar combined = clicks.CombineLatest(valueStream, (c, v) => Format(c, v));","handlingStrategy":"validation","validationCode":"if (second == null) throw new InvalidOperationException(\"second source required\"); // or: second ??= Observable.Empty<TSource2>();","typeGuard":"bool IsStreamReady(IObservable<TSource2>? second) => second is not null;","tryCatchPattern":"try { var result = first.CombineLatest(second, selector); } catch (ArgumentNullException ex) when (ex.ParamName == \"second\") { /* substitute Observable.Empty<TSource2>() */ }","preventionTips":["Substitute Observable.Empty<T>() for optional streams rather than null.","Check DI registrations so optional streams always resolve.","Keep stream fields readonly and initialize them at construction."],"tags":["rx","argument-null","combinelatest"],"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"}