{"record":{"id":"ec79065c95bc1422","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-observer-selectmany","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'observer')","messagePattern":"Value cannot be null\\. \\(Parameter 'observer'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/SelectMany.cs","lineNumber":187,"sourceCode":"                source,\n                (collectionSelector, resultSelector),\n                static async (source, state, observer) =>\n                {\n                    var (sink, inner) = AsyncObserver.SelectMany(observer, state.collectionSelector, state.resultSelector);\n\n                    var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(subscription, inner);\n                });\n        }\n    }\n\n    public partial class AsyncObserver\n    {\n        public static (IAsyncObserver<TSource>, IAsyncDisposable) SelectMany<TSource, TResult>(IAsyncObserver<TResult> observer, Func<TSource, IAsyncObservable<TResult>> selector)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (selector == null)\n                throw new ArgumentNullException(nameof(selector));\n\n            return SelectMany<TSource, TResult, TResult>(observer, x => new ValueTask<IAsyncObservable<TResult>>(selector(x)), (x, y) => new ValueTask<TResult>(y));\n        }\n\n        public static (IAsyncObserver<TSource>, IAsyncDisposable) SelectMany<TSource, TResult>(IAsyncObserver<TResult> observer, Func<TSource, ValueTask<IAsyncObservable<TResult>>> selector)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (selector == null)\n                throw new ArgumentNullException(nameof(selector));\n\n            return SelectMany<TSource, TResult, TResult>(observer, selector, (x, y) => new ValueTask<TResult>(y));\n        }\n\n        public static (IAsyncObserver<TSource>, IAsyncDisposable) SelectMany<TSource, TCollection, TResult>(IAsyncObserver<TResult> observer, Func<TSource, IAsyncObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)\n        {","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/SelectMany.cs#L169-L205","documentation":"The AsyncObserver.SelectMany factory (observer-side overload taking IAsyncObserver<TResult> and a Func<TSource, IAsyncObservable<TResult>> selector) throws ArgumentNullException because the observer parameter was null. This overload adapts a downstream observer into a SelectMany pipeline; without an observer there is nothing to forward events to, so construction fails immediately.","triggerScenarios":"Calling AsyncObserver.SelectMany<TSource, TResult>(null, selector), or passing an observer variable that a factory/composition method returned as null.","commonSituations":"Building custom operator pipelines where the downstream observer comes from another operator's return value that silently returned null, misordered tuple construction of (observer, disposable) pairs, or typo'd variable assignment in observer-chain setup.","solutions":["Pass a valid IAsyncObserver<TResult> instance as the first argument.","If composing, verify the upstream expression producing the observer (e.g. AsyncObserver.Create...) actually returned non-null.","Use the higher-level AsyncObservable.SelectMany on the observable instead of manually wiring observer-side factories.","Assert the observer argument at the call site before invoking AsyncObserver.SelectMany."],"exampleFix":"// before\nvar (obs, disp) = AsyncObserver.SelectMany<TSource, TResult>(null, x => inner);\n\n// after\nvar downstream = AsyncObserver.Create<TResult>(onNextAsync, onErrorAsync, onCompletedAsync);\nvar (obs, disp) = AsyncObserver.SelectMany(downstream, x => inner);","handlingStrategy":"validation","validationCode":"if (observer is null) throw new ArgumentNullException(nameof(observer));\nif (selector is null) throw new ArgumentNullException(nameof(selector));","typeGuard":"static bool IsValidObserverArgs<TSource, TResult>(\n    IAsyncObserver<TResult> observer,\n    Func<TSource, IAsyncObservable<TResult>> selector)\n    => observer is not null && selector is not null;","tryCatchPattern":"try\n{\n    var (obs, disp) = AsyncObserver.SelectMany(observer, selector);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"observer\")\n{\n    observer = AsyncObserver.Create<TResult>(...); // substitute a no-op observer\n}","preventionTips":["Always construct observers via AsyncObserver.Create or an operator, never hold nullable observer variables.","Check the return of any method that yields an observer before passing it on.","Favor the observable-level SelectMany + SubscribeAsync API to avoid manual observer wiring."],"tags":["argument-null","asyncrx","observer","selectmany"],"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"}