dotnet/reactive · error · ArgumentOutOfRangeException

Specified argument was out of range of valid values…

Error message

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

What it means

In the selector overload Replay(source, selector, bufferSize, window, scheduler), bufferSize must be >= 0 and is validated eagerly; a negative value throws ArgumentOutOfRangeException (parameter 'bufferSize').

Solutions

  1. Clamp with Math.Max(0, bufferSize) before the call
  2. Correct the arithmetic/config producing the negative number
  3. Add a startup range validation for configured sizes

Example fix

// before
var replayed = source.Replay(sel, size - taken /* -3 */, window, scheduler);
// after
var n = Math.Max(0, size - taken);
var replayed = source.Replay(sel, n, window, scheduler);
Defensive patterns

Strategy: validation

Validate before calling

if (bufferSize < 0) throw new ArgumentOutOfRangeException(nameof(bufferSize));

Type guard

static bool IsValidBufferSize(int bufferSize) => bufferSize >= 0;

Try / catch

try { var r = src.Replay(sel, bufferSize, window, scheduler); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "bufferSize") { bufferSize = 0; /* retry */ }

Prevention

When it happens

Trigger: Calling source.Replay(selector, negativeN, window, scheduler) with a negative replay count, e.g. from underflowing arithmetic or an unparsed/negative config value.

Common situations: Buffer capacity computed as a difference that went negative; user or config supplied replay count without validation; copying a call site and forgetting to update the size constant.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs:922

        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> or <paramref name="scheduler"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
        /// <seealso cref="ReplaySubject{T}"/>
        public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window, IScheduler scheduler)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

            if (bufferSize < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(bufferSize));
            }

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

            if (scheduler == null)
            {
                throw new ArgumentNullException(nameof(scheduler));
            }

            return s_impl.Replay(source, selector, bufferSize, window, scheduler);
        }

        #endregion
    }
}

View on GitHub (pinned to 94b5d5ab91)