dotnet/reactive · error · ArgumentOutOfRangeException
duration
Error message
duration
What it means
The time-based SkipLast overload throws ArgumentOutOfRangeException("duration") when the duration is negative (less than TimeSpan.Zero). The operator needs a non-negative window during which trailing elements are dropped. Zero is explicitly allowed and short-circuits to the source.
Solutions
- Clamp the duration: if (duration < TimeSpan.Zero) duration = TimeSpan.Zero;
- Validate config/user input for non-negative durations before composing the pipeline.
- Fix the arithmetic producing negative TimeSpans (clamp against now/deadline).
Example fix
// before var res = source.SkipLast(deadline - clock.Now); // may be negative // after var d = deadline - clock.Now; var res = source.SkipLast(d < TimeSpan.Zero ? TimeSpan.Zero : d);
Defensive patterns
Strategy: validation
Validate before calling
if (duration < TimeSpan.Zero) duration = TimeSpan.Zero; var res = source.SkipLast(duration);
Type guard
static bool IsValidDuration(TimeSpan d) => d >= TimeSpan.Zero;
Try / catch
try { var res = source.SkipLast(duration); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "duration") { var res = source; } Prevention
- Clamp deadline-based durations against TimeSpan.Zero.
- Validate configured durations are non-negative at load time.
- Be careful with TimeSpan arithmetic around deadlines/clock skew.
When it happens
Trigger: Calling source.SkipLast(TimeSpan.FromSeconds(-1)) or passing a TimeSpan computed by subtraction where the subtrahend is larger (e.g. deadline - now after the deadline).
Common situations: Timeout math going negative; user-provided configuration accepting negative values; clock skew when durations are derived from timestamps.
Related errors
- throw new ArgumentOutOfRangeException(nameof(dueTime));
- Specified argument was out of the range of valid values…
- nameof(index)
- capacity
- 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/6ddbded5af421d74.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/SkipLast.cs:37
if (count == 0)
{
return source;
}
return CreateAsyncObservable<TSource>.From(
source,
count,
static (source, count, observer) => source.SubscribeSafeAsync(AsyncObserver.SkipLast(observer, count)));
}
public static IAsyncObservable<TSource> SkipLast<TSource>(this IAsyncObservable<TSource> source, TimeSpan duration)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (duration < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(duration));
if (duration == TimeSpan.Zero)
{
return source;
}
return CreateAsyncObservable<TSource>.From(
source,
duration,
static (source, duration, observer) => source.SubscribeSafeAsync(AsyncObserver.SkipLast(observer, duration)));
}
public static IAsyncObservable<TSource> SkipLast<TSource>(this IAsyncObservable<TSource> source, TimeSpan duration, IClock clock)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (duration < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(duration));View on GitHub (pinned to 94b5d5ab91)