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 'dueTime')

What it means

Throttle(source, dueTime) throws ArgumentOutOfRangeException when dueTime is negative. The throttle window is a duration that must be zero or positive; a negative TimeSpan has no valid meaning for the scheduled delay and the library rejects it at argument validation.

Solutions

  1. Pass a non-negative TimeSpan, e.g. TimeSpan.FromMilliseconds(500).
  2. Clamp or Math.Abs the computed duration before passing it in.
  3. Validate config-supplied durations (reject negatives) at startup.

Example fix

// before
var delta = end - start; // can be negative
source.Throttle(delta); // throws if negative
// after
var delta = end - start;
if (delta < TimeSpan.Zero) delta = TimeSpan.Zero;
source.Throttle(delta);
Defensive patterns

Strategy: validation

Validate before calling

if (dueTime < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(dueTime), dueTime, "dueTime must be non-negative");
// or clamp: dueTime = dueTime < TimeSpan.Zero ? TimeSpan.Zero : dueTime;

Type guard

static bool IsValidDueTime(TimeSpan t) => t >= TimeSpan.Zero;

Try / catch

try { return source.Throttle(dueTime); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "dueTime") { return source.Throttle(TimeSpan.Zero); }

Prevention

When it happens

Trigger: Calling source.Throttle(TimeSpan.FromMilliseconds(-1)) or passing a dueTime computed by subtracting timestamps (e.g. TimeSpan.FromTicks(endTicks - startTicks) where the subtraction went negative) or a misconfigured config value like '-500ms'.

Common situations: Durations parsed from user config or CLI flags without sign validation; clock/timezone math producing negative deltas; tests with placeholder negative values.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/7f0439008d527226. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs:1445

        /// Observable.Sample set of operators.
        /// </para>
        /// <para>
        /// Specifying a TimeSpan.Zero value for <paramref name="dueTime"/> is not recommended but supported, causing throttling timers to be scheduled
        /// that are due immediately. However, this doesn't guarantee all elements will be retained in the result sequence. This is a side-effect of the
        /// asynchrony introduced by the scheduler, where the action to forward the current element may not execute immediately, despite the TimeSpan.Zero
        /// due time. In such cases, the next element may arrive before the scheduler gets a chance to run the throttling action.
        /// </para>
        /// </remarks>
        public static IObservable<TSource> Throttle<TSource>(this IObservable<TSource> source, TimeSpan dueTime)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (dueTime < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(dueTime));
            }

            return s_impl.Throttle(source, dueTime);
        }

        /// <summary>
        /// Ignores elements from an observable sequence which are followed by another element within a specified relative time duration, using the specified scheduler to run throttling timers.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence to throttle.</param>
        /// <param name="dueTime">Throttling duration for each element.</param>
        /// <param name="scheduler">Scheduler to run the throttle timers on.</param>
        /// <returns>The throttled sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="dueTime"/> is less than TimeSpan.Zero.</exception>
        /// <remarks>
        /// <para>
        /// This operator throttles the source sequence by holding on to each element for the duration specified in <paramref name="dueTime"/>. If another

View on GitHub (pinned to 94b5d5ab91)