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 'time')
What it means
AdvanceTo moves the virtual clock forward to an absolute time, running all due work. If the requested time compares earlier than the current Clock (Comparer.Compare(time, Clock) < 0), time would run backwards, which virtual time cannot do, so ArgumentOutOfRangeException is thrown.
Solutions
- Pass a time >= scheduler.Clock; clamp with Math.Max(time, scheduler.Clock) if monotonicity is uncertain.
- Use GetNow()/scheduler.Clock as the reference instead of a stale stored value.
- Reorder test steps so AdvanceTo targets increase monotonically, or use a fresh scheduler instance.
Example fix
// before scheduler.AdvanceTo(0); // Clock already at 100 // after scheduler.AdvanceTo(Math.Max(0, scheduler.Clock));
Defensive patterns
Strategy: validation
Validate before calling
if (scheduler.Comparer.Compare(time, scheduler.Clock) < 0)
throw new ArgumentOutOfRangeException(nameof(time), "time is before the current scheduler clock"); Type guard
bool CanAdvanceTo<TAbsolute>(VirtualTimeSchedulerBase<TAbsolute, TRelative> s, TAbsolute t) where TAbsolute : IComparable<TAbsolute> => s.Comparer.Compare(t, s.Clock) >= 0;
Try / catch
try { scheduler.AdvanceTo(time); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "time") { /* clamp or use scheduler.Clock instead */ } Prevention
- Track the current clock via scheduler.Clock rather than stored timestamps.
- Keep a monotonic list of target times in test scenarios and assert each is >= the last.
- Clamp targets with Math.Max relative to the clock when order is uncertain.
When it happens
Trigger: Calling AdvanceTo(t) where t < scheduler.Clock, e.g. calling AdvanceTo(0) after the clock already advanced, or passing a time captured before earlier AdvanceTo/AdvanceBy calls.
Common situations: Test sequences where steps are reordered or times are hardcoded and overlap; reusing a stale timestamp variable across test cases; mixing AdvanceTo with an already-advanced TestScheduler.
Related errors
- Specified argument was out of the range of valid values…
- Specified argument was out of the range of valid values…
- Specified argument was out of the range of valid values…
- count
- duration
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/03d19cbfc49d3907.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Concurrency/VirtualTimeScheduler.cs:208
/// Stops the virtual time scheduler.
/// </summary>
public void Stop()
{
IsEnabled = false;
}
/// <summary>
/// Advances the scheduler's clock to the specified time, running all work till that point.
/// </summary>
/// <param name="time">Absolute time to advance the scheduler's clock to.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is in the past.</exception>
/// <exception cref="InvalidOperationException">The scheduler is already running. VirtualTimeScheduler doesn't support running nested work dispatch loops. To simulate time slippage while running work on the scheduler, use <see cref="Sleep"/>.</exception>
public void AdvanceTo(TAbsolute time)
{
var dueToClock = Comparer.Compare(time, Clock);
if (dueToClock < 0)
{
throw new ArgumentOutOfRangeException(nameof(time));
}
if (dueToClock == 0)
{
return;
}
if (!IsEnabled)
{
IsEnabled = true;
do
{
var next = GetNext();
if (next != null && Comparer.Compare(next.DueTime, time) <= 0)
{
if (Comparer.Compare(next.DueTime, Clock) > 0)
{
Clock = next.DueTime;View on GitHub (pinned to 94b5d5ab91)