{"record":{"id":"696df6a2fab0c36a","repo":"dotnet/reactive","slug":"argumentnullexception-source-windowsobservable","errorCode":null,"errorMessage":"ArgumentNullException: source","messagePattern":"ArgumentNullException: source","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Linq/WindowsObservable.StandardSequenceOperators.cs","lineNumber":30,"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":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Linq/WindowsObservable.StandardSequenceOperators.cs#L12-L48","documentation":"This Windows Runtime-specific SelectMany overload maps each element to an IAsyncOperation and flattens the results, and it throws ArgumentNullException when the source observable is null. Rx operators validate arguments eagerly before composing, so the throw happens immediately at call time rather than on subscription.","triggerScenarios":"Calling source.SelectMany<TSource, TResult>((Func<TSource, IAsyncOperation<TResult>>)selector) with a null source observable.","commonSituations":"An async data-fetch method returned null instead of an empty observable; chaining operators on a nullable field; a WinRT API wrapper returning null when no operation is available.","solutions":["Pass a non-null IObservable<TSource>; return Observable.Empty<TSource>() when there is no data.","Null-check the source before entering the LINQ chain.","Fix the upstream producer so it never returns null observables."],"exampleFix":"// before\nIObservable<TResult> result = GetDataObservable()?.SelectMany(x => x.ToAsyncOp()); // may be null\n// after\nvar source = GetDataObservable() ?? Observable.Empty<DataSource>();\nIObservable<TResult> result = source.SelectMany(x => x.ToAsyncOp());","handlingStrategy":"validation","validationCode":"if (source is null) throw new InvalidOperationException(\"source observable must be created before SelectMany\");","typeGuard":"static bool IsSourceReady<T>(IObservable<T>? s) => s is not null;","tryCatchPattern":"try { var q = source.SelectMany(x => x.ToAsyncOperation()); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"source\") { q = Observable.Empty<TResult>(); }","preventionTips":["Standardize on factories that return Observable.Empty instead of null.","Null-check pipeline inputs once at the boundary, not at every operator.","Use 'var source = maybeSource ?? Observable.Empty<T>();' as a defensive idiom."],"tags":["argument-null","reactive-extensions","uwp","linq"],"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"}