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 'window')
What it means
The window parameter of Replay(source, bufferSize, window, scheduler) defines the time span for which notifications are replayed and must not be negative. A negative TimeSpan is rejected eagerly with ArgumentOutOfRangeException (message parameter 'window').
Solutions
- Pass a non-negative TimeSpan (use TimeSpan.Zero for no window trimming)
- Apply TimeSpan.FromTicks(Math.Abs(ts.Ticks)) if the value is derived from a difference
- Validate the configured duration at startup
Example fix
// before var conn = source.Replay(10, TimeSpan.FromSeconds(-5), scheduler); // after var conn = source.Replay(10, TimeSpan.FromSeconds(5), scheduler);
Defensive patterns
Strategy: validation
Validate before calling
if (window < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(window));
Type guard
static bool IsValidWindow(TimeSpan window) => window >= TimeSpan.Zero;
Try / catch
try { var conn = src.Replay(size, window, scheduler); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "window") { window = TimeSpan.Zero; /* retry */ } Prevention
- Use Math.Abs when windows derive from timestamp differences
- Parse duration config with sign checks
- Define non-negative TimeSpan constants for defaults
When it happens
Trigger: Calling source.Replay(bufferSize, negativeTimeSpan, scheduler), e.g. TimeSpan.FromSeconds(-5) or a TimeSpan computed by subtraction (later - earlier) that came out negative.
Common situations: Duration loaded from config where units were misread (milliseconds vs seconds) yielding a negative value; clock/timestamp subtraction without Math.Abs; refactored constant with a stray minus sign.
Related errors
- period (Parameter 'period')
- Specified argument was out of the range of valid values…
- Specified argument was out of the range of valid values…
- action
- action (Parameter 'action')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/5b18c42781813880.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs:881
/// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSize"/> is less than zero.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="window"/> is less than TimeSpan.Zero.</exception>
/// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>
/// <seealso cref="ReplaySubject{T}"/>
public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize, TimeSpan window, IScheduler scheduler)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
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, bufferSize, window, scheduler);
}
/// <summary>
/// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length and element count for the replay buffer.
/// This operator is a specialization of Multicast using a <see cref="ReplaySubject{T}"/>.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <param name="source">Source sequence whose elements will be multicasted through a single shared subscription.</param>
/// <param name="selector">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>View on GitHub (pinned to 94b5d5ab91)