{"record":{"id":"11dca0a7b884a61a","repo":"dotnet/reactive","slug":"source-windowsobservable-standardsequenceoperators","errorCode":null,"errorMessage":"source","messagePattern":"source","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/WindowsObservable.StandardSequenceOperators.cs","lineNumber":27,"sourceCode":"namespace System.Reactive.Linq\n{\n    public static partial class WindowsObservable\n    {\n        /// <summary>\n        /// Projects each element of an observable sequence to a Windows Runtime asynchronous operation and merges all of the asynchronous operation results into one observable sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the result produced by the projected asynchronous operations and the elements in the merged result sequence.</typeparam>\n        /// <param name=\"source\">An observable sequence of elements to project.</param>\n        /// <param name=\"selector\">A transform function to apply to each element.</param>\n        /// <returns>An observable sequence whose elements are the result of the asynchronous operations executed for each element of the input sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"selector\"/> is null.</exception>\n        /// <remarks>This overload supports composition of observable sequences and Windows Runtime asynchronous operations, without requiring manual conversion of the asynchronous operations to observable sequences using <see cref=\"AsyncInfoObservableExtensions.ToObservable{TResult}(IAsyncOperation{TResult})\"/>.</remarks>\n        public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IAsyncOperation<TResult>> selector)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (selector == null)\n            {\n                throw new ArgumentNullException(nameof(selector));\n            }\n\n            return source.SelectMany(x => selector(x).ToObservable());\n        }\n\n        /// <summary>\n        /// Projects each element of an observable sequence to a Windows Runtime asynchronous operation and merges all of the asynchronous operation results into one observable sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the result produced by the projected asynchronous operations and the elements in the merged result sequence.</typeparam>\n        /// <typeparam name=\"TProgress\">The type of the reported progress objects, which get ignored by this query operator.</typeparam>\n        /// <param name=\"source\">An observable sequence of elements to project.</param>\n        /// <param name=\"selector\">A transform function to apply to each element.</param>","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/WindowsObservable.StandardSequenceOperators.cs#L9-L45","documentation":"This SelectMany overload projects each element into a WinRT IAsyncOperation and throws ArgumentNullException when the source observable is null (the selector null check follows). Rx validates arguments eagerly before composing the async-operation sequence.","triggerScenarios":"Calling source.SelectMany(x => x.DoAsync()) where source is a null IObservable<TSource>, or where an upstream factory returned null; the selector returning null is a separate failure at runtime.","commonSituations":"Chaining SelectMany after a null-conditional expression on an optional service; passing the result of an async factory that returned null instead of throwing; WinRT async interop where the source was conditionally created.","solutions":["Ensure the source observable is non-null before calling SelectMany","Also verify the selector itself is non-null (next guard)","Wrap optional sources: source ?? Observable.Empty<TSource>()","Ensure async factories throw on failure rather than returning null observables"],"exampleFix":"// before\nIObservable<StorageFile> files = null;\nfiles.SelectMany(f => f.OpenAsync()).Subscribe(...);\n// after\nIObservable<StorageFile> files = GetFiles() ?? Observable.Empty<StorageFile>();\nfiles.SelectMany(f => f.OpenAsync()).Subscribe(...);","handlingStrategy":"validation","validationCode":"if (source == null) throw new ArgumentNullException(nameof(source));\nif (selector == null) throw new ArgumentNullException(nameof(selector));","typeGuard":"static IObservable<TResult> SafeSelectMany<T, TResult>(IObservable<T> source, Func<T, Windows.Foundation.IAsyncOperation<TResult>> selector) => source?.SelectMany(selector) ?? Observable.Empty<TResult>();","tryCatchPattern":"try { obs.SelectMany(x => x.DoAsync()).Subscribe(...); }\ncatch (ArgumentNullException ex) { Log($\"{ex.ParamName} null in SelectMany\"); }","preventionTips":["Ensure async factories return empty observables instead of null on failure","Guard null-conditional chains feeding Rx operators","Default observable fields to Observable.Never or Observable.Empty","Enable nullable reference types so null sources surface at compile time"],"tags":["rx","null-argument","winrt","async","argument-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"}