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 'timeShift')

What it means

Buffer(source, timeSpan, timeShift) throws ArgumentOutOfRangeException when timeShift, the period between the starts of consecutive buffers, is negative. The shift must be zero or positive; negative shifts would move buffer boundaries into the past.

Solutions

  1. Clamp timeShift to TimeSpan.Zero or greater before the call
  2. Verify argument order: Buffer(source, timeSpan, timeShift) — window first, shift second
  3. Fix the computation or configuration that yields the negative shift

Example fix

// before
source.Buffer(window, latestTick - previousTick); // can be negative
// after
var shift = latestTick > previousTick ? latestTick - previousTick : TimeSpan.Zero;
source.Buffer(window, shift);
Defensive patterns

Strategy: validation

Validate before calling

if (timeShift < TimeSpan.Zero)
    throw new ArgumentOutOfRangeException(nameof(timeShift), timeShift, "Shift must be non-negative");

Type guard

static bool IsValidShift(TimeSpan s) => s >= TimeSpan.Zero;

Try / catch

try { source.Buffer(window, shift); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "timeShift")
{
    shift = TimeSpan.Zero;
    source.Buffer(window, shift);
}

Prevention

When it happens

Trigger: Observable.Buffer(source, window, negativeShift), commonly when shift is computed as an offset subtraction that underflows, or when window/shift arguments are swapped and one is negative.

Common situations: Swapped arguments (passing the shift where the window belongs) with a negative value; negative config value for a polling/shift interval; dynamic rate calculations producing negative intervals.

Related errors


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

Appendix: source

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

        /// However, this doesn't mean all buffers will start at the beginning of the source sequence. This is a side-effect of the asynchrony introduced by the scheduler,
        /// where the action to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.
        /// </para>
        /// </remarks>
        public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, TimeSpan timeShift)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

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

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

            return s_impl.Buffer(source, timeSpan, timeShift);
        }

        /// <summary>
        /// Projects each element of an observable sequence into zero or more buffers which are produced based on timing information, using the specified scheduler to run timers.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
        /// <param name="source">Source sequence to produce buffers over.</param>
        /// <param name="timeSpan">Length of each buffer.</param>
        /// <param name="timeShift">Interval between creation of consecutive buffers.</param>
        /// <param name="scheduler">Scheduler to run buffering timers on.</param>
        /// <returns>An observable sequence of buffers.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> or <paramref name="timeSpan"/> is less than TimeSpan.Zero.</exception>
        /// <remarks>
        /// <para>

View on GitHub (pinned to 94b5d5ab91)