dotnet/reactive · error · ArgumentOutOfRangeException
throw new ArgumentOutOfRangeException(nameof(timeSpan));
Error message
throw new ArgumentOutOfRangeException(nameof(timeSpan));
What it means
The timeSpan/count Buffer overload throws ArgumentOutOfRangeException when timeSpan is negative. Buffer windows are durations used to schedule buffer closings, so a negative TimeSpan has no meaning. The operator validates this eagerly before subscribing.
Solutions
- Pass a positive TimeSpan, e.g. TimeSpan.FromSeconds(1)
- Clamp computed durations with TimeSpan.FromTicks(Math.Max(0, ticks)) before passing
- Validate configuration values at startup so negative timeouts never reach Rx operators
Example fix
// before var ts = end - start; // can be negative var buffered = source.Buffer(ts, 10); // after var ts = end - start; if (ts < TimeSpan.Zero) ts = TimeSpan.Zero; var buffered = source.Buffer(ts, 10);
Defensive patterns
Strategy: validation
Validate before calling
if (timeSpan < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(timeSpan)); // or clamp: timeSpan = timeSpan < TimeSpan.Zero ? TimeSpan.Zero : timeSpan;
Try / catch
try { var b = source.Buffer(timeSpan, count); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "timeSpan") { /* correct the window and retry */ } Prevention
- Clamp any computed duration with Math.Max(TimeSpan.Zero, value)
- Validate TimeSpan settings when loading configuration
- Watch the operand order when subtracting DateTime/Stopwatch values
When it happens
Trigger: Calling Observable.Buffer(source, timeSpan, count) with timeSpan < TimeSpan.Zero, e.g. TimeSpan.FromMilliseconds(-1) or a computed duration that went negative due to clock subtraction.
Common situations: Computing a duration by subtracting DateTime/Stopwatch values where the end precedes the start; misconfigured timeout settings loaded as negative values; sign errors in TimeSpan arithmetic.
Related errors
- throw new ArgumentOutOfRangeException(nameof(dueTime));
- Specified argument was out of the range of valid values…
- Specified argument was out of the range of valid values…
- period (Parameter 'period')
- Specified argument was out of the range of valid values…
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/113fa78784396018.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs:199
/// <param name="count">Maximum element count of a window.</param>
/// <returns>An observable sequence of buffers.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="timeSpan"/> is less than TimeSpan.Zero. -or- <paramref name="count"/> is less than or equal to zero.</exception>
/// <remarks>
/// Specifying a TimeSpan.Zero value for <paramref name="timeSpan"/> is not recommended but supported, causing the scheduler to create buffers as fast as it can.
/// Because all source sequence elements end up in one of the buffers, some buffers won't have a zero time span. This is a side-effect of the asynchrony introduced
/// by the scheduler, where the action to close the current buffer and to create a new buffer may not execute immediately, despite the TimeSpan.Zero due time.
/// </remarks>
public static IObservable<IList<TSource>> Buffer<TSource>(this IObservable<TSource> source, TimeSpan timeSpan, int count)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (timeSpan < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(timeSpan));
}
if (count <= 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}
return s_impl.Buffer(source, timeSpan, count);
}
/// <summary>
/// Projects each element of an observable sequence into a buffer that's sent out when either it's full or a given amount of time has elapsed, using the specified scheduler to run timers.
/// A useful real-world analogy of this overload is the behavior of a ferry leaving the dock when all seats are taken, or at the scheduled time of departure, whichever event occurs first.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence, and in the lists in the result sequence.</typeparam>
/// <param name="source">Source sequence to produce buffers over.</param>
/// <param name="timeSpan">Maximum time length of a buffer.</param>
/// <param name="count">Maximum element count of a buffer.</param>View on GitHub (pinned to 94b5d5ab91)