{"record":{"id":"d46def4fb878cd8c","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-taskselector","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'taskSelector')","messagePattern":"Value cannot be null\\. \\(Parameter 'taskSelector'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.StandardSequenceOperators.cs","lineNumber":1253,"sourceCode":"        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TTaskResult\">The type of the results produced by the projected intermediate tasks.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate task results.</typeparam>\n        /// <param name=\"source\">An observable sequence of elements to project.</param>\n        /// <param name=\"taskSelector\">A transform function to apply to each element.</param>\n        /// <param name=\"resultSelector\">A transform function to apply to each element of the intermediate sequence.</param>\n        /// <returns>An observable sequence whose elements are the result of obtaining a task for each element of the input sequence and then mapping the task's result and its corresponding source element to a result element.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"taskSelector\"/> or <paramref name=\"resultSelector\"/> is null.</exception>\n        /// <remarks>This overload supports using LINQ query comprehension syntax in C# and Visual Basic to compose observable sequences and tasks, without requiring manual conversion of the tasks to observable sequences using <see cref=\"TaskObservableExtensions.ToObservable{TResult}(Task{TResult})\"/>.</remarks>\n        public static IObservable<TResult> SelectMany<TSource, TTaskResult, TResult>(this IObservable<TSource> source, Func<TSource, Task<TTaskResult>> taskSelector, Func<TSource, TTaskResult, TResult> resultSelector)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (taskSelector == null)\n            {\n                throw new ArgumentNullException(nameof(taskSelector));\n            }\n\n            if (resultSelector == null)\n            {\n                throw new ArgumentNullException(nameof(resultSelector));\n            }\n\n            return s_impl.SelectMany(source, taskSelector, resultSelector);\n        }\n\n        /// <summary>\n        /// Projects each element of an observable sequence to a task by incorporating the element's index, invokes the result selector for the source element and the task result, and merges the results into one observable sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TTaskResult\">The type of the results produced by the projected intermediate tasks.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate task results.</typeparam>\n        /// <param name=\"source\">An observable sequence of elements to project.</param>\n        /// <param name=\"taskSelector\">A transform function to apply to each element; the second parameter of the function represents the index of the source element.</param>","sourceCodeStart":1235,"sourceCodeEnd":1271,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.StandardSequenceOperators.cs#L1235-L1271","documentation":"The task-based SelectMany overload requires a non-null taskSelector delegate that maps each source element to a Task<TTaskResult>. A null taskSelector would make it impossible to produce the inner sequences, so the operator throws ArgumentNullException synchronously before returning an observable. Rx throws these argument-null exceptions eagerly at call time rather than delivering them through the stream.","triggerScenarios":"Calling Observable.SelectMany(source, taskSelector, resultSelector) where taskSelector is null - typically a null lambda variable, an uninitialized Func field, or a conditional expression that resolved to null.","commonSituations":"Storing selector delegates in nullable fields or configuration-driven lookups that fail to resolve; passing the result of a method that returns Func<TSource, Task<T>>? when the mapping is not registered; copy-paste refactors that removed the lambda body.","solutions":["Pass a non-null lambda or method group as the taskSelector argument","Check any Func field/property feeding the call and initialize it before use","If the selector is optional, branch: use a different overload or Observable.Empty when no selector is available","Wrap the operator call in a guard that throws a descriptive exception naming the missing selector"],"exampleFix":"// before\nFunc<int, Task<string>>? loader = _config.EnableFetch ? FetchAsync : null;\nvar result = source.SelectMany(loader, (x, r) => r); // throws when null\n\n// after\nvar result = _config.EnableFetch\n    ? source.SelectMany(FetchAsync, (x, r) => r)\n    : Observable.Empty<string>();","handlingStrategy":"validation","validationCode":"if (taskSelector is null) throw new ArgumentNullException(nameof(taskSelector));","typeGuard":"static bool HasSelector<TSource, TRes>(Func<TSource, Task<TRes>>? selector) => selector is not null;","tryCatchPattern":"try { var result = source.SelectMany(taskSelector, resultSelector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"taskSelector\") { /* supply a default selector or skip the operation */ }","preventionTips":["Prefer method groups over nullable delegate fields","Resolve delegates at startup/configuration time, not per-call","Enable nullable reference types so Func fields declared nullable surface the risk"],"tags":["rx","null-argument","delegate","system-reactive"],"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"}