{"record":{"id":"3bc6a9b6332d6c68","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-bufferopenings","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'bufferOpenings')","messagePattern":"Value cannot be null\\. \\(Parameter 'bufferOpenings'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs","lineNumber":124,"sourceCode":"        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>\n        /// <typeparam name=\"TBufferOpening\">The type of the elements in the sequence indicating buffer opening events, also passed to the closing selector to obtain a sequence of buffer closing events.</typeparam>\n        /// <typeparam name=\"TBufferClosing\">The type of the elements in the sequences indicating buffer closing events.</typeparam>\n        /// <param name=\"source\">Source sequence to produce buffers over.</param>\n        /// <param name=\"bufferOpenings\">Observable sequence whose elements denote the creation of new buffers.</param>\n        /// <param name=\"bufferClosingSelector\">A function invoked to define the closing of each produced buffer.</param>\n        /// <returns>An observable sequence of buffers.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"bufferOpenings\"/> or <paramref name=\"bufferClosingSelector\"/> is null.</exception>\n        public static IObservable<IList<TSource>> Buffer<TSource, TBufferOpening, TBufferClosing>(this IObservable<TSource> source, IObservable<TBufferOpening> bufferOpenings, Func<TBufferOpening, IObservable<TBufferClosing>> bufferClosingSelector)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (bufferOpenings == null)\n            {\n                throw new ArgumentNullException(nameof(bufferOpenings));\n            }\n\n            if (bufferClosingSelector == null)\n            {\n                throw new ArgumentNullException(nameof(bufferClosingSelector));\n            }\n\n            return s_impl.Buffer(source, bufferOpenings, bufferClosingSelector);\n        }\n\n        /// <summary>\n        /// Projects each element of an observable sequence into consecutive non-overlapping buffers.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>\n        /// <typeparam name=\"TBufferBoundary\">The type of the elements in the sequences indicating buffer boundary events.</typeparam>\n        /// <param name=\"source\">Source sequence to produce buffers over.</param>\n        /// <param name=\"bufferBoundaries\">Sequence of buffer boundary markers. The current buffer is closed and a new buffer is opened upon receiving a boundary marker.</param>\n        /// <returns>An observable sequence of buffers.</returns>","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs#L106-L142","documentation":"The Buffer(source, bufferOpenings, bufferClosingSelector) overload requires a non-null bufferOpenings observable that signals when each buffer starts. Passing null for bufferOpenings throws ArgumentNullException at call time. The library validates arguments eagerly so the failure surfaces at the call site, not inside the subscription.","triggerScenarios":"Calling source.Buffer(openings, selector) where the openings IObservable<TBufferOpening> is null — e.g. an event stream that was never wired up, a Subject that failed to initialize, or a null result from a lookup of opening events.","commonSituations":"Dynamic UI/event wiring where the opening-signal stream is conditionally created; a service returning null instead of Observable.Empty for the opening stream; copy-pasted operator calls where the openings argument was accidentally dropped or left as an uninitialized variable.","solutions":["Initialize or fix the bufferOpenings observable so it is non-null before calling Buffer.","Substitute Observable.Empty<TBufferOpening>() when there are genuinely no openings (yields no buffers).","Guard the call: only invoke Buffer when both source and openings streams are available."],"exampleFix":"// before\nvar buffers = source.Buffer(maybeOpenings, x => closings); // throws if maybeOpenings is null\n// after\nvar openings = maybeOpenings ?? Observable.Empty<Opening>();\nvar buffers = source.Buffer(openings, x => closings);","handlingStrategy":"validation","validationCode":"ArgumentNullException.ThrowIfNull(openings);\nvar openings = maybeOpenings ?? Observable.Empty<TBufferOpening>();","typeGuard":"bool HasOpenings<TBufferOpening>(IObservable<TBufferOpening>? openings) => openings is not null;","tryCatchPattern":"try { var buffers = source.Buffer(openings, closingSelector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"bufferOpenings\") { /* supply Observable.Empty<TBufferOpening>() */ }","preventionTips":["Never return null for an event/opening stream; return Observable.Empty or Observable.Never.","Wire opening subjects/streams during initialization before any operator is composed.","Use nullable annotations on fields holding boundary streams to catch missing wiring."],"tags":["argument-null","rx","buffer","argument-validation"],"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"}