{"record":{"id":"0329d7e95e35973f","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-handlers-concat","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'handlers')","messagePattern":"Value cannot be null\\. \\(Parameter 'handlers'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Concat.cs","lineNumber":92,"sourceCode":"                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        }\n\n        public static (IAsyncObserver<TSource>, IAsyncDisposable) Concat<TSource>(IAsyncObserver<TSource> observer, IEnumerator<IAsyncObservable<TSource>> handlers)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (handlers == null)\n                throw new ArgumentNullException(nameof(handlers));\n\n            var innerSubscription = new SerialAsyncDisposable();\n\n            IAsyncObserver<TSource> GetSink() =>\n                Create<TSource>(\n                    observer.OnNextAsync,\n                    observer.OnErrorAsync,\n                    async () =>\n                    {\n                        var next = default(IAsyncObservable<TSource>);\n\n                        try\n                        {\n                            if (handlers.MoveNext())\n                            {\n                                next = handlers.Current;\n                            }\n                        }","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Concat.cs#L74-L110","documentation":"AsyncObserver.Concat<TSource>(observer, handlers) throws ArgumentNullException naming 'handlers' when the IEnumerator<IAsyncObservable<TSource>> is null. The enumerator supplies the sequences to be concatenated, so it cannot be null (an empty enumerator is fine).","triggerScenarios":"Calling AsyncObserver.Concat(observer, null), e.g. passing result of a method that returned null instead of an enumerator, or passing the enumerator of a null collection.","commonSituations":"Dynamic source lists from config/DI where obtaining the enumerator happened on a null collection; mapping null lists to enumerators without a null check.","solutions":["Pass a non-null IEnumerator<IAsyncObservable<TSource>>","Guard the source collection first: if (list == null) use an empty list's enumerator","Default to an empty enumerator to mean 'concatenate nothing' rather than null"],"exampleFix":"// before\nvar (sink, disp) = AsyncObserver.Concat(observer, sources.GetEnumerator()); // sources is null\n// after\nvar enumerator = (sources ?? new List<IAsyncObservable<int>>()).GetEnumerator();\nvar (sink, disp) = AsyncObserver.Concat(observer, enumerator);","handlingStrategy":"validation","validationCode":"if (handlers is null) handlers = (Enumerable.Empty<IAsyncObservable<TSource>>()).GetEnumerator();","typeGuard":"public static bool HasHandlers<T>(IEnumerator<IAsyncObservable<T>>? e) => e is not null;","tryCatchPattern":"try { var (sink, disp) = AsyncObserver.Concat(observer, handlers); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"handlers\") { /* use an empty enumerator */ }","preventionTips":["Null-check the source collection before calling GetEnumerator()","Represent 'no sequences' with an empty enumerator, never null","Null-coalesce collections from config/DI before enumerating"],"tags":["argument-null","enumerator","concat","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"}