{"record":{"id":"67eb967f0df5c7b7","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-timeshift","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'timeShift')","messagePattern":"Value cannot be null\\. \\(Parameter 'timeShift'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs","lineNumber":92,"sourceCode":"                (timeSpan, scheduler),\n                static async (source, state, observer) =>\n                {\n                    var (sink, timer) = await AsyncObserver.Buffer(observer, state.timeSpan, state.scheduler).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, TimeSpan timeShift)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (timeSpan < TimeSpan.Zero)\n                throw new ArgumentNullException(nameof(timeSpan));\n            if (timeShift < TimeSpan.Zero)\n                throw new ArgumentNullException(nameof(timeShift));\n\n            return CreateAsyncObservable<IList<TSource>>.From(\n                source,\n                (timeSpan, timeShift),\n                static async (source, state, observer) =>\n                {\n                    var (sink, timer) = await AsyncObserver.Buffer(observer, state.timeSpan, state.timeShift).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, TimeSpan timeShift, IAsyncScheduler scheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs#L74-L110","documentation":"The Buffer(source, timeSpan, timeShift) overload throws ArgumentNullException naming 'timeShift'. The guard is `timeShift < TimeSpan.Zero`, so the message \"Value cannot be null\" is misleading: the actual trigger is a negative time-shift value. timeShift controls how far apart successive buffer windows start, so it must be non-negative.","triggerScenarios":"Calling source.Buffer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(-2)) or passing a computed shift that went negative (e.g. shift = interval - drift with drift > interval).","commonSituations":"Adaptive scheduling logic where the shift is derived from measured latencies and can go negative under load, or config typos like '-2s'.","solutions":["Clamp the shift: Math.Max(TimeSpan.Zero, timeShift) before calling Buffer.","Review the computation producing timeShift for sign errors or subtracting unbounded values.","Validate user/config supplied shift values at load time so negatives never reach the operator."],"exampleFix":"// before\nvar shift = interval - measuredDrift; // can be negative\nvar buffer = source.Buffer(interval, shift);\n// after\nvar shift = interval - measuredDrift;\nif (shift < TimeSpan.Zero) shift = TimeSpan.Zero;\nvar buffer = source.Buffer(interval, shift);","handlingStrategy":"validation","validationCode":"if (timeShift < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(timeShift), timeShift, \"Time shift must be non-negative\");\nvar buffered = source.Buffer(timeSpan, timeShift);","typeGuard":"static bool IsValidShift(TimeSpan shift) => shift >= TimeSpan.Zero;","tryCatchPattern":"try { var b = source.Buffer(timeSpan, timeShift); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"timeShift\") { log.Warn(\"Negative timeShift passed to Buffer\"); timeShift = TimeSpan.Zero; }","preventionTips":["Clamp measured/derived shifts (latency compensation, drift offsets) to zero minimum.","Scan config files for accidental negative duration literals.","Validate shift > 0 (or >= 0, per intent) in a settings-validation step.","Keep shift computations explicit; avoid inline arithmetic that can silently go negative."],"tags":["argument-validation","timespan","reactive-extensions","asyncrx"],"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"}