{"record":{"id":"5f764124029ebe1b","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-observer-concat","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/Concat.cs","lineNumber":67,"sourceCode":"                }\n\n                var source = enumerator.Current;\n\n                var (sink, inner) = AsyncObserver.Concat(observer, enumerator);\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) Concat<TSource>(IAsyncObserver<TSource> observer, IAsyncObservable<TSource> second)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (second == null)\n                throw new ArgumentNullException(nameof(second));\n\n            var subscription = new SingleAssignmentAsyncDisposable();\n\n            var sink = Create<TSource>(\n                observer.OnNextAsync,\n                observer.OnErrorAsync,\n                async () =>\n                {\n                    var secondSubscription = await second.SubscribeSafeAsync(observer).ConfigureAwait(false);\n\n                    await subscription.AssignAsync(secondSubscription).ConfigureAwait(false);\n                }\n            );\n\n            return (sink, subscription);\n        }","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Concat.cs#L49-L85","documentation":"AsyncObserver.Concat<TSource>(observer, second) throws ArgumentNullException naming 'observer' when the downstream observer is null. This factory wires a continuation observer that resubscribes to 'second' after the current sequence completes, so a valid observer is mandatory.","triggerScenarios":"Calling AsyncObserver.Concat(null, second) when hand-rolling operators or sinks, e.g. passing an observer field that was never initialized.","commonSituations":"Custom operator implementations where the observer is threaded through several constructors and arrives null due to a wiring/ordering bug.","solutions":["Pass a non-null IAsyncObserver<TSource> as the observer argument","Check how the observer is created and propagated in your custom operator/sink code","Use SubscribeSafeAsync on a real observable rather than manually constructing observer sinks when possible"],"exampleFix":"// before\nvar (sink, disp) = AsyncObserver.Concat(observer, second); // observer is null\n// after\nif (observer == null) throw new InvalidOperationException(\"observer not initialized\");\nvar (sink, disp) = AsyncObserver.Concat(observer, second);","handlingStrategy":"validation","validationCode":"if (observer is null) throw new ArgumentNullException(nameof(observer));","typeGuard":"public static bool HasObserver<T>(IAsyncObserver<T>? o) => o is not null;","tryCatchPattern":"try { var (sink, disp) = AsyncObserver.Concat(observer, second); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"observer\") { /* initialize observer before building sink */ }","preventionTips":["Initialize observer fields before constructing sinks","Enable nullable reference types in custom operator code","Prefer high-level AsyncObservable operators over manual observer composition"],"tags":["argument-null","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"}