dotnet/reactive · error · ArgumentOutOfRangeException
window
Error message
window
What it means
The Replay(source, selector, window) overload throws ArgumentOutOfRangeException because the window TimeSpan was negative. The window defines how long past elements stay replayable in the SequentialReplayAsyncSubject, so only TimeSpan.Zero or positive durations are valid. The library rejects negatives eagerly at the call site.
Solutions
- Pass a non-negative TimeSpan (TimeSpan.Zero is allowed).
- Clamp before calling: window < TimeSpan.Zero ? TimeSpan.Zero : window.
- Fix the computation or configuration source that produced the negative duration.
Example fix
// before var replayed = source.Replay(selector, expiry - now); // can be negative // after var window = expiry > now ? expiry - now : TimeSpan.Zero; var replayed = source.Replay(selector, window);
Defensive patterns
Strategy: validation
Validate before calling
if (window < TimeSpan.Zero) throw new InvalidOperationException("window must be >= TimeSpan.Zero");
// safe to call source.Replay(selector, window); Type guard
bool IsValidWindow(TimeSpan t) => t >= TimeSpan.Zero;
Try / catch
try { var r = source.Replay(selector, window); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "window") { /* clamp to TimeSpan.Zero and retry */ } Prevention
- Clamp durations: window < TimeSpan.Zero ? TimeSpan.Zero : window.
- Check sign when subtracting DateTimes to compute a window.
- Validate user/config-supplied durations at load time.
When it happens
Trigger: Calling source.Replay(selector, TimeSpan.FromSeconds(-5)) or passing a TimeSpan computed from a subtraction/deserialized config value that ended up negative.
Common situations: Window read from configuration with an invalid unit conversion (ms vs s producing negative values); TimeSpan arithmetic that underflows (later - earlier with reversed operands); user-supplied duration not validated upstream.
Related errors
- Specified argument was out of the range of valid values…
- duration
- duration
- throw new ArgumentOutOfRangeException(nameof(dueTime));
- ArgumentOutOfRangeException
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/7d2d406e7e8062a7.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Replay.cs:158
throw new ArgumentNullException(nameof(source));
if (selector == null)
throw new ArgumentNullException(nameof(selector));
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
return Multicast(source, () => new SequentialReplayAsyncSubject<TSource>(bufferSize, scheduler), selector);
}
public static IAsyncObservable<TResult> Replay<TSource, TResult>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, IAsyncObservable<TResult>> selector, TimeSpan window)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (selector == null)
throw new ArgumentNullException(nameof(selector));
if (window < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(window));
return Multicast(source, () => new SequentialReplayAsyncSubject<TSource>(window), selector);
}
public static IAsyncObservable<TResult> Replay<TSource, TResult>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, IAsyncObservable<TResult>> selector, TimeSpan window, IAsyncScheduler scheduler)
{
if (source == null)
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 SequentialReplayAsyncSubject<TSource>(window, scheduler), selector);
}
View on GitHub (pinned to 94b5d5ab91)