dotnet/reactive · error · ArgumentOutOfRangeException

Specified argument was out of the range of valid values…

Error message

Specified argument was out of the range of valid values. (Parameter 'duration')

What it means

TakeLastBuffer(source, duration) throws ArgumentOutOfRangeException when the duration TimeSpan is negative. Only non-negative time windows are meaningful for collecting the trailing buffer, so the library rejects negative values before delegating to the implementation.

Solutions

  1. Validate the TimeSpan is >= TimeSpan.Zero before calling
  2. Clamp negative durations to TimeSpan.Zero or fix the computation
  3. Correct the source of the timestamps/configuration that produced the negative value

Example fix

// before
var buf = source.TakeLastBuffer(windowEnd - windowStart);
// after
var dur = windowEnd - windowStart;
if (dur < TimeSpan.Zero) throw new InvalidOperationException("window end before start");
var buf = source.TakeLastBuffer(dur);
Defensive patterns

Strategy: validation

Validate before calling

if (duration < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(duration));

Try / catch

try { var buf = source.TakeLastBuffer(dur); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "duration") { /* clamp or report config error */ }

Prevention

When it happens

Trigger: Calling TakeLastBuffer(source, TimeSpan.FromSeconds(-3)); computing the window via subtraction where the end time precedes the start time.

Common situations: User-supplied window configuration that can go negative; DateTime subtraction across clock adjustments; off-by-sign bugs in generated durations.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/4c69bfad61aad5f0. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs:1322

        /// <param name="source">Source sequence to take elements from.</param>
        /// <param name="duration">Duration for taking elements from the end of the sequence.</param>
        /// <returns>An observable sequence containing a single list with the elements taken during the specified duration from the end of the source sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
        /// <remarks>
        /// This operator accumulates a buffer with a length enough to store elements for any <paramref name="duration"/> window during the lifetime of
        /// the source sequence. Upon completion of the source sequence, this buffer is produced on the result sequence.
        /// </remarks>
        public static IObservable<IList<TSource>> TakeLastBuffer<TSource>(this IObservable<TSource> source, TimeSpan duration)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (duration < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(duration));
            }

            return s_impl.TakeLastBuffer(source, duration);
        }

        /// <summary>
        /// Returns a list with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence to take elements from.</param>
        /// <param name="duration">Duration for taking elements from the end of the sequence.</param>
        /// <param name="scheduler">Scheduler to run the timer on.</param>
        /// <returns>An observable sequence containing a single list with the elements taken during the specified duration from the end of the source sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="duration"/> is less than TimeSpan.Zero.</exception>
        /// <remarks>
        /// This operator accumulates a buffer with a length enough to store elements for any <paramref name="duration"/> window during the lifetime of
        /// the source sequence. Upon completion of the source sequence, this buffer is produced on the result sequence.

View on GitHub (pinned to 94b5d5ab91)