dotnet/reactive · error · ArgumentOutOfRangeException
throw new ArgumentOutOfRangeException(nameof(bufferSize));
Error message
throw new ArgumentOutOfRangeException(nameof(bufferSize));
What it means
The Replay(source, selector, bufferSize, window) operator validates bufferSize before creating a SequentialReplayAsyncSubject. It throws ArgumentOutOfRangeException when bufferSize is negative, because a replay buffer cannot hold a negative number of items. Only negative values are rejected; 0 is allowed (no buffered history, only live notification).
Solutions
- Pass a non-negative bufferSize (0 for replay-live-only, int.MaxValue for unlimited history).
- Clamp the value before the call: bufferSize = Math.Max(0, computedSize).
- Validate configuration inputs at startup so negative sizes never reach the operator.
Example fix
// before var replayed = AsyncObservable.Replay(source, sel, bufferSize: -1, window: TimeSpan.FromSeconds(5)); // after if (bufferSize < 0) bufferSize = 0; var replayed = AsyncObservable.Replay(source, sel, bufferSize, window: TimeSpan.FromSeconds(5));
Defensive patterns
Strategy: validation
Validate before calling
if (bufferSize < 0) throw new ArgumentException("bufferSize must be >= 0", nameof(bufferSize)); Try / catch
try { var replayed = AsyncObservable.Replay(source, sel, bufferSize, window); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "bufferSize") { /* use 0 or int.MaxValue and retry construction */ } Prevention
- Never use -1 to mean 'unlimited' with this API; use int.MaxValue.
- Validate buffer-size configuration at startup.
- Clamp computed sizes with Math.Max(0, size).
When it happens
Trigger: Calling AsyncObservable.Replay(source, selector, bufferSize, window) with a bufferSize parameter that is < 0, e.g. a computed size from an unvalidated config value or a subtraction underflow like newSize - removedItems.
Common situations: Reading bufferSize from appsettings/environment variables without validation; computing a buffer size with integer arithmetic that goes negative; copying a call site from another operator and passing an unrelated negative value.
Related errors
- throw new ArgumentOutOfRangeException(nameof(retryCount));
- Value cannot be null. (Parameter 'timeShift')
- new ArgumentOutOfRangeException(nameof(capacity))
- ArgumentOutOfRangeException: capacity
- Value cannot be null. (Parameter 'observer')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/f4efd5c8d0e7b707.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Replay.cs:288
throw new ArgumentNullException(nameof(source));
if (selector == null)
throw new ArgumentNullException(nameof(selector));
if (window < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(window));
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
return Multicast(source, () => new ValueTask<IAsyncSubject<TSource, TSource>>(new SequentialReplayAsyncSubject<TSource>(window, scheduler)), selector);
}
public static IAsyncObservable<TResult> Replay<TSource, TResult>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, ValueTask<IAsyncObservable<TResult>>> selector, int bufferSize, TimeSpan window)
{
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));
return Multicast(source, () => new ValueTask<IAsyncSubject<TSource, TSource>>(new SequentialReplayAsyncSubject<TSource>(bufferSize, window)), selector);
}
public static IAsyncObservable<TResult> Replay<TSource, TResult>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, ValueTask<IAsyncObservable<TResult>>> selector, int bufferSize, TimeSpan window, IAsyncScheduler 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));View on GitHub (pinned to 94b5d5ab91)