{"record":{"id":"b325a68e1425e476","repo":"dotnet/reactive","slug":"argumentnullexception-selector-windowsobservable","errorCode":null,"errorMessage":"ArgumentNullException: selector","messagePattern":"ArgumentNullException: selector","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Linq/WindowsObservable.StandardSequenceOperators.cs","lineNumber":35,"sourceCode":"        /// 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>\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, TProgress>(this IObservable<TSource> source, Func<TSource, IAsyncOperationWithProgress<TResult, TProgress>> selector)\n        {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Linq/WindowsObservable.StandardSequenceOperators.cs#L17-L53","documentation":"This SelectMany overload (selector returning IAsyncOperation<TResult>) throws ArgumentNullException when the selector delegate is null. The selector is invoked per element to produce the WinRT async operation, so a null delegate makes the composition impossible. Validation is eager, before any subscription.","triggerScenarios":"Calling source.SelectMany<TSource, TResult>(selector) where the Func<TSource, IAsyncOperation<TResult>> argument is null.","commonSituations":"A selector stored in a field, injected dependency, or dictionary that was never initialized; passing a null method group from optional configuration; refactoring removed the lambda but left the call.","solutions":["Supply a non-null selector lambda, e.g. x => x.CreateAsyncOperation().","Null-check injected/configured selectors before building the query.","Ensure DI registrations or factory methods actually provide the selector delegate."],"exampleFix":"// before\nFunc<Item, IAsyncOperation<Result>> sel = _config.Selector; // may be null\nvar q = source.SelectMany(sel);\n// after\nvar selector = _config.Selector ?? throw new InvalidOperationException(\"Selector not configured\");\nvar q = source.SelectMany(x => selector(x));","handlingStrategy":"validation","validationCode":"if (selector is null) throw new InvalidOperationException(\"selector delegate must be configured before SelectMany\");","typeGuard":"static bool HasSelector<T, R>(Func<T, IAsyncOperation<R>>? f) => f is not null;","tryCatchPattern":"try { var q = source.SelectMany(selector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"selector\") { /* fail with clear configuration error */ }","preventionTips":["Require selector delegates in constructors and validate with ArgumentNullException.ThrowIfNull at injection time.","Avoid dictionary lookups for delegates without a TryGetValue + null check.","Write selectors as inline lambdas when they are not genuinely dynamic."],"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"}