{"record":{"id":"f07b35467350b26e","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-bufferclosingselector","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'bufferClosingSelector')","messagePattern":"Value cannot be null\\. \\(Parameter 'bufferClosingSelector'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs","lineNumber":205,"sourceCode":"                static async (source, bufferBoundaries, observer) =>\n                {\n                    var (sourceObserver, boundariesObserver) = AsyncObserver.Buffer<TSource, TBufferBoundary>(observer);\n\n                    var sourceSubscription = await source.SubscribeSafeAsync(sourceObserver).ConfigureAwait(false);\n                    var boundariesSubscription = await bufferBoundaries.SubscribeSafeAsync(boundariesObserver).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(sourceSubscription, boundariesSubscription);\n                });\n        }\n\n        // REVIEW: This overload is inherited from Rx but arguably a bit esoteric as it doesn't provide context to the closing selector.\n\n        public static IAsyncObservable<IList<TSource>> Buffer<TSource, TBufferClosing>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TBufferClosing>> bufferClosingSelector)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (bufferClosingSelector == null)\n                throw new ArgumentNullException(nameof(bufferClosingSelector));\n\n            return CreateAsyncObservable<IList<TSource>>.From(\n                source,\n                bufferClosingSelector,\n                static async (source, bufferClosingSelector, observer) =>\n                {\n                    var (sourceObserver, closingDisposable) = await AsyncObserver.Buffer<TSource, TBufferClosing>(observer, bufferClosingSelector).ConfigureAwait(false);\n\n                    var sourceSubscription = await source.SubscribeSafeAsync(sourceObserver).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(sourceSubscription, closingDisposable);\n                });\n        }\n    }\n\n    public partial class AsyncObserver\n    {\n        public static IAsyncObserver<TSource> Buffer<TSource>(IAsyncObserver<IList<TSource>> observer, int count) => Buffer(observer, count, count);","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs#L187-L223","documentation":"Genuine ArgumentNullException: the closing-selector overload Buffer(source, bufferClosingSelector) requires a non-null factory Func<IAsyncObservable<TBufferClosing>> that is called for each buffer to obtain its closing observable; passing null is rejected immediately.","triggerScenarios":"Calling Buffer(source, null); passing a method group whose target is null, or a selector field not yet assigned.","commonSituations":"Selector supplied via dependency injection or configuration of delegates that was never registered; refactoring removed the selector assignment.","solutions":["Pass a valid selector, e.g. () => someClosingObservable","Default the selector at the call site if it is optional: selector ?? DefaultClosingSelector","Ensure the delegate is registered/assigned before composition","Use a time/count Buffer overload when no closing selector is needed"],"exampleFix":"// before\nvar buf = src.Buffer(bufferClosingSelector);\n// after\nvar buf = src.Buffer(bufferClosingSelector ?? (Func<IAsyncObservable<TBufferClosing>>)(() => AsyncObservable.Never<TBufferClosing>()));","handlingStrategy":"type-guard","validationCode":"if (bufferClosingSelector == null) throw new InvalidOperationException(\"bufferClosingSelector must be provided\");","typeGuard":"static Func<IAsyncObservable<C>> RequireSelector<C>(Func<IAsyncObservable<C>> f) => f ?? (() => AsyncObservable.Never<C>());","tryCatchPattern":"try { var buf = source.Buffer(bufferClosingSelector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"bufferClosingSelector\")\n{\n    var buf = source.Buffer(TimeSpan.FromSeconds(30), 100);\n}","preventionTips":["Assign delegate dependencies before pipeline composition","Provide a default closing selector for optional configuration","Prefer built-in time/count overloads when no per-buffer closing logic exists","Verify DI-registered delegates resolve non-null at startup"],"tags":["null-reference","arguments","reactive","delegate"],"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"}