{"record":{"id":"4d2085019f8b0c48","repo":"dotnet/reactive","slug":"observer-merge","errorCode":null,"errorMessage":"observer","messagePattern":"observer","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Merge.cs","lineNumber":36,"sourceCode":"                throw new ArgumentNullException(nameof(source));\n\n            return Create<TSource>(async observer =>\n            {\n                var (sink, cancel) = AsyncObserver.Merge(observer);\n\n                var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);\n\n                return StableCompositeAsyncDisposable.Create(subscription, cancel);\n            });\n        }\n    }\n\n    public partial class AsyncObserver\n    {\n        public static (IAsyncObserver<IAsyncObservable<TSource>>, IAsyncDisposable) Merge<TSource>(IAsyncObserver<TSource> observer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n\n            var gate = new AsyncGate();\n\n            var count = 1;\n\n            var disposable = new CompositeAsyncDisposable();\n\n            async ValueTask OnErrorAsync(Exception ex)\n            {\n                using (await gate.LockAsync().ConfigureAwait(false))\n                {\n                    await observer.OnErrorAsync(ex).ConfigureAwait(false);\n                }\n            };\n\n            async ValueTask OnCompletedAsync()\n            {\n                using (await gate.LockAsync().ConfigureAwait(false))","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Merge.cs#L18-L54","documentation":"AsyncObserver.Merge's sink factory throws ArgumentNullException when the downstream observer is null. The sink needs a valid observer to forward merged inner-stream events to. This surfaces when composing operator sinks manually rather than through the extension method.","triggerScenarios":"Calling AsyncObserver.Merge<TSource>(null) while wiring a custom async-observable pipeline.","commonSituations":"Hand-rolled operator chains where an upstream Create(...) returned null; passing an observer before it is constructed.","solutions":["Pass a valid IAsyncObserver<TSource> created earlier in the pipeline","Use the public extension source.Merge() which supplies the observer automatically","Make the observer producer non-null-returning (throw earlier with a clearer message)"],"exampleFix":"// before\nvar (sink, cancel) = AsyncObserver.Merge<int>(null);\n// after\nvar (sink, cancel) = AsyncObserver.Merge<int>(observer);","handlingStrategy":"validation","validationCode":"if (observer == null) throw new InvalidOperationException(\"Merge sink requires an observer\");","typeGuard":"bool HasObserver<T>(IAsyncObserver<T> o) => o is not null;","tryCatchPattern":"try { var (sink, cancel) = AsyncObserver.Merge(observer); } catch (ArgumentNullException ex) when (ex.ParamName == \"observer\") { /* reconstruct observer */ }","preventionTips":["Use source.Merge() extension instead of manual sink wiring","Create observers before calling AsyncObserver factories","Assert observer non-null in pipeline builders"],"tags":["argument-null","merge","observer","async-rx"],"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"}