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
In the sliding time Window, timeShift is the interval between window starts and must be non-negative. The operator throws ArgumentOutOfRangeException when it is negative because window start times would regress in time, an unschedulable configuration.
Solutions
- Clamp or recompute the shift to be >= TimeSpan.Zero before calling Window
- Check argument order — ensure timeSpan (length) is passed before timeShift (period)
- Fix the producer of the negative duration (config parsing, timestamp subtraction)
Example fix
// before await AsyncObservable.Window(observer, subscription, shift, windowLen, scheduler); // args swapped // after await AsyncObservable.Window(observer, subscription, windowLen, shift < TimeSpan.Zero ? TimeSpan.Zero : shift, scheduler);
Defensive patterns
Strategy: validation
Validate before calling
if (timeShift < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(timeShift)); var safeShift = TimeSpan.Max(TimeSpan.Zero, timeShift);
Type guard
static bool IsValidShift(TimeSpan t) => t >= TimeSpan.Zero;
Try / catch
try
{
await AsyncObservable.Window(observer, subscription, timeSpan, timeShift, scheduler);
}
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "timeShift")
{
// fix argument order or clamp the shift
} Prevention
- Double-check timeSpan vs timeShift argument order (length before period)
- Clamp percentages/deltas used to derive shift values
- Unit-test window composition with boundary durations (0, 1 tick)
When it happens
Trigger: Passing a negative TimeSpan as the timeShift argument (4th parameter) of Window(observer, subscription, timeSpan, timeShift[, scheduler]) — e.g. a computed shift that went negative or swapped the timeShift/timeSpan arguments.
Common situations: Swapping timeSpan and timeShift where one is negative; deriving the shift from a percentage or delta that can go below zero; parsing durations from settings where negatives are not screened.
Related errors
- nameof(finallyAction)
- nameof(source)
- nameof(predicate)
- Value cannot be null. (Parameter 'observer')
- ArgumentNullException
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/3886fcc8e7178323.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Window.cs:381
refCount
);
}
return CoreAsync();
}
public static ValueTask<(IAsyncObserver<TSource>, IAsyncDisposable)> Window<TSource>(IAsyncObserver<IAsyncObservable<TSource>> observer, IAsyncDisposable subscription, TimeSpan timeSpan, TimeSpan timeShift) => Window(observer, subscription, timeSpan, timeShift, TaskPoolAsyncScheduler.Default);
public static ValueTask<(IAsyncObserver<TSource>, IAsyncDisposable)> Window<TSource>(IAsyncObserver<IAsyncObservable<TSource>> observer, IAsyncDisposable subscription, TimeSpan timeSpan, TimeSpan timeShift, IAsyncScheduler scheduler)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (subscription == null)
throw new ArgumentNullException(nameof(subscription));
if (timeSpan < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(timeSpan));
if (timeShift < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(timeShift));
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
var gate = new AsyncGate();
var d = new CompositeAsyncDisposable();
var timer = new SerialAsyncDisposable();
var refCount = new RefCountAsyncDisposable(d);
var queue = new Queue<IAsyncSubject<TSource>>();
var nextOpen = timeShift;
var nextClose = timeSpan;
var totalTime = TimeSpan.Zero;
var isOpen = false;
var isClose = false;
View on GitHub (pinned to 94b5d5ab91)