{"record":{"id":"e20161258ef1fe32","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-timespan","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'timeSpan')","messagePattern":"Value cannot be null\\. \\(Parameter 'timeSpan'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs","lineNumber":48,"sourceCode":"            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (count <= 0)\n                throw new ArgumentNullException(nameof(count));\n            if (skip <= 0)\n                throw new ArgumentNullException(nameof(skip));\n\n            return CreateAsyncObservable<IList<TSource>>.From(\n                source,\n                (count, skip),\n                static (source, state, observer) => source.SubscribeSafeAsync(AsyncObserver.Buffer(observer, state.count, state.skip)));\n        }\n\n        public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, TimeSpan timeSpan)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (timeSpan < TimeSpan.Zero)\n                throw new ArgumentNullException(nameof(timeSpan));\n\n            return CreateAsyncObservable<IList<TSource>>.From(\n                source,\n                timeSpan,\n                static async (source, timeSpan, observer) =>\n                {\n                    var (sink, timer) = await AsyncObserver.Buffer(observer, timeSpan).ConfigureAwait(false);\n\n                    var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(subscription, timer);\n                });\n        }\n\n        public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, TimeSpan timeSpan, IAsyncScheduler scheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs#L30-L66","documentation":"Buffer<TSource>(source, timeSpan) throws ArgumentNullException(nameof(timeSpan)) when timeSpan < TimeSpan.Zero. A negative buffer window is meaningless (a window cannot have negative duration), so the operator rejects it. Semantically this is an out-of-range value, but the library throws ArgumentNullException with the parameter name 'timeSpan'. The check runs at pipeline-construction time.","triggerScenarios":"Calling source.Buffer(TimeSpan.FromSeconds(-1)) or a TimeSpan computed by subtraction (e.g. end - start where end < start) yielding a negative duration.","commonSituations":"Window duration derived from clock arithmetic that can go negative near boundaries; config values parsed with a sign error; Duration properties defaulted to -1 as a sentinel and passed through unvalidated.","solutions":["Ensure the TimeSpan is >= TimeSpan.Zero before calling; clamp: if (ts < TimeSpan.Zero) ts = TimeSpan.Zero; (or a sensible positive default).","Fix the computation producing the negative duration (e.g. clamp end >= start before subtracting).","Validate configured durations at startup and reject negative values with a clear error."],"exampleFix":"// before\nvar window = end - start; // end < start -> negative\nvar batches = source.Buffer(window);\n// after\nvar window = end > start ? end - start : TimeSpan.FromSeconds(1);\nvar batches = source.Buffer(window);","handlingStrategy":"validation","validationCode":"if (timeSpan < TimeSpan.Zero) throw new ArgumentException(\"Buffer window must be non-negative\", nameof(timeSpan));","typeGuard":"bool IsValidWindow(TimeSpan ts) => ts >= TimeSpan.Zero;","tryCatchPattern":"try { var batches = source.Buffer(timeSpan); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"timeSpan\") { throw new InvalidOperationException(\"Buffer window must be >= TimeSpan.Zero; check duration computation\", ex); }","preventionTips":["Clamp clock-derived durations: window = end > start ? end - start : TimeSpan.Zero","Never use negative TimeSpans as 'unset' sentinels without validating first","Validate configured durations at startup"],"tags":["argumentnull","argument-range","asyncrx","buffer","timespan"],"backgroundTag":"argument-out-of-range","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"}