{"record":{"id":"42220fbd5c58886c","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-source-observable-time","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'source')","messagePattern":"Value cannot be null\\. \\(Parameter 'source'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs","lineNumber":34,"sourceCode":"        /// <summary>\n        /// Projects each element of an observable sequence into consecutive non-overlapping buffers which are produced based on timing information.\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        /// <param name=\"source\">Source sequence to produce buffers over.</param>\n        /// <param name=\"timeSpan\">Length of each buffer.</param>\n        /// <returns>An observable sequence of buffers.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> is null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"timeSpan\"/> is less than TimeSpan.Zero.</exception>\n        /// <remarks>\n        /// Specifying a TimeSpan.Zero value for <paramref name=\"timeSpan\"/> is not recommended but supported, causing the scheduler to create buffers as fast as it can.\n        /// Because all source sequence elements end up in one of the buffers, some buffers won't have a zero time span. This is a side-effect of the asynchrony introduced\n        /// by the scheduler, where the action to close the current buffer and to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.\n        /// </remarks>\n        public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (timeSpan < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(timeSpan));\n            }\n\n            return s_impl.Buffer(source, timeSpan);\n        }\n\n        /// <summary>\n        /// Projects each element of an observable sequence into consecutive non-overlapping buffers which are produced based on timing information, using the specified scheduler to run timers.\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        /// <param name=\"source\">Source sequence to produce buffers over.</param>\n        /// <param name=\"timeSpan\">Length of each buffer.</param>\n        /// <param name=\"scheduler\">Scheduler to run buffering timers on.</param>\n        /// <returns>An observable sequence of buffers.</returns>","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs#L16-L52","documentation":"The time-based Buffer(source, timeSpan) operator in Observable.Time.cs validates the source observable first and throws ArgumentNullException when it is null. Time-based operators additionally need the source to schedule buffer windows, so a null source is rejected immediately before any scheduling setup.","triggerScenarios":"Calling source.Buffer(TimeSpan.FromSeconds(1)) where source is null — e.g. a null-returning producer, an unset event-to-observable conversion result, or a DI dependency not registered.","commonSituations":"Event streams built from Observable.FromEventPattern where the backing hookup returned null; timers/telemetry streams that are conditionally created; null scheduler/source fields in services composing time-windowed pipelines.","solutions":["Ensure the upstream producer returns Observable.Empty<T>() or a valid observable instead of null.","Coalesce before buffering: `(source ?? Observable.Empty<T>()).Buffer(timeSpan)`.","Validate inputs at service construction so the null is caught long before the Rx chain runs."],"exampleFix":"// before\nvar windows = telemetry.Buffer(TimeSpan.FromSeconds(5)); // telemetry == null\n\n// after\nvar windows = (telemetry ?? Observable.Empty<Metric>()).Buffer(TimeSpan.FromSeconds(5));","handlingStrategy":"validation","validationCode":"if (source is null) source = Observable.Empty<TSource>(); // before time-based Buffer\nif (timeSpan < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(timeSpan));","typeGuard":"bool HasSource<T>(IObservable<T>? s) => s is not null;","tryCatchPattern":"try { var r = src.Buffer(timeSpan); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"source\") { /* use Observable.Empty<T>() */ }","preventionTips":["Ensure event/telemetry stream producers never return null.","Coalesce nullable streams before time-windowed operators.","Validate composed pipelines in constructor or startup checks."],"tags":["rx","argument-null","buffer","time","dotnet"],"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"}