dotnet/reactive · error · ArgumentOutOfRangeException
period (Specified argument was out of the range of valid…
Error message
period (Specified argument was out of the range of valid values)
What it means
SchedulePeriodic<TState>(IScheduler, TState, TimeSpan, Func<TState,TState>) throws ArgumentOutOfRangeException when period < TimeSpan.Zero. A negative period is meaningless for a periodic timer; Rx rejects it up front instead of scheduling an invalid sequence of ticks. TimeSpan.Zero is allowed (period invoked immediately/repeatedly per scheduler semantics).
Solutions
- Clamp or validate the period before calling: if (period < TimeSpan.Zero) period = TimeSpan.Zero; or throw with your own message
- Fix the computation producing the negative TimeSpan (check the order of subtraction operands and units)
- If the interval comes from config, validate it at load time and reject negative values with a clear error
Example fix
// before var period = nextRun - DateTime.Now; // can be negative scheduler.SchedulePeriodic(state, period, s => s); // after var period = nextRun - DateTime.Now; if (period < TimeSpan.Zero) period = TimeSpan.Zero; scheduler.SchedulePeriodic(state, period, s => s);
Defensive patterns
Strategy: validation
Validate before calling
if (period < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(period), period, "Period must be non-negative"); scheduler.SchedulePeriodic(state, period, action);
Type guard
bool IsValidPeriod(TimeSpan p) => p >= TimeSpan.Zero;
Try / catch
try { scheduler.SchedulePeriodic(state, period, action); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "period") { /* clamp to Zero or report config error */ } Prevention
- Validate all interval config values at startup
- Use System.TimeSpan.From* factories rather than raw ticks arithmetic
- Check subtraction order when computing intervals from timestamps
When it happens
Trigger: Calling SchedulePeriodic with a TimeSpan computed to be negative, e.g. TimeSpan.FromSeconds(-1), a subtraction of DateTime values yielding negative duration, or deserialized/converted config values such as 'PT-5S' producing a negative TimeSpan.
Common situations: Configuration parsing errors where a delay/interval value is negative, subtracting a later timestamp from an earlier one to compute an interval, integer arithmetic overflow wrapping negative, or unit confusion (treating a value in seconds when it was milliseconds).
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…
- Value cannot be null. (Parameter 'scheduler')
- scheduler
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/191d4bad8fe92a00.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Services.Emulation.cs:37
/// </summary>
/// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
/// <param name="scheduler">The scheduler to run periodic work on.</param>
/// <param name="state">Initial state passed to the action upon the first iteration.</param>
/// <param name="period">Period for running the work periodically.</param>
/// <param name="action">Action to be executed, potentially updating the state.</param>
/// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>
/// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="action"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than <see cref="TimeSpan.Zero"/>.</exception>
public static IDisposable SchedulePeriodic<TState>(this IScheduler scheduler, TState state, TimeSpan period, Func<TState, TState> action)
{
if (scheduler == null)
{
throw new ArgumentNullException(nameof(scheduler));
}
if (period < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(period));
}
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
return SchedulePeriodic_(scheduler, state, period, action);
}
/// <summary>
/// Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities.
/// If the scheduler supports periodic scheduling, the request will be forwarded to the periodic scheduling implementation.
/// If the scheduler provides stopwatch functionality, the periodic task will be emulated using recursive scheduling with a stopwatch to correct for time slippage.
/// Otherwise, the periodic task will be emulated using recursive scheduling.
/// </summary>
/// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
/// <param name="scheduler">Scheduler to execute the action on.</param>View on GitHub (pinned to 94b5d5ab91)