dotnet/reactive · error · ArgumentOutOfRangeException
Specified argument was out of range of valid values…
Error message
Specified argument was out of range of valid values. (Parameter 'duration')
What it means
Take(source, duration) requires a non-negative TimeSpan; a negative duration is invalid (it would mean taking elements from before the start) and throws ArgumentOutOfRangeException. TimeSpan.Zero is valid and yields an empty observable.
Solutions
- Clamp the duration: if (d < TimeSpan.Zero) d = TimeSpan.Zero;
- Return Empty<T>() early when the computed window is non-positive
- Validate configured duration values at startup
Example fix
// before var window = source.Take(deadline - DateTime.Now); // may be negative // after var d = deadline - DateTime.Now; var window = d > TimeSpan.Zero ? source.Take(d) : AsyncObservable.Empty<T>();
Defensive patterns
Strategy: validation
Validate before calling
if (duration < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(duration)); var window = source.Take(duration);
Type guard
bool IsValidDuration(TimeSpan d) => d >= TimeSpan.Zero;
Try / catch
try { var window = source.Take(duration); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "duration") { /* treat as elapsed: use Empty */ } Prevention
- Clamp deadline-derived durations to TimeSpan.Zero minimum
- Validate parsed duration configuration values
- Handle already-elapsed deadlines before building the window
When it happens
Trigger: Calling source.Take(negativeTimeSpan), typically from a computed window such as endTime - now when now is past endTime.
Common situations: Deadline-based windows where the deadline already elapsed, or a configuration value parsed as a negative duration.
Related errors
- nameof(index)
- capacity
- Specified argument was out of the range of valid values…
- ArgumentOutOfRangeException: capacity
- duration
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/025d7f2339bbbc19.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Take.cs:37
throw new ArgumentOutOfRangeException(nameof(count));
if (count == 0)
{
return Empty<TSource>();
}
return CreateAsyncObservable<TSource>.From(
source,
count,
static (source, count, observer) => source.SubscribeSafeAsync(AsyncObserver.Take(observer, count)));
}
public static IAsyncObservable<TSource> Take<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 Empty<TSource>();
}
// REVIEW: May be easier to just use TakeUntil with a Timer parameter. Do we want Take on the observer?
return CreateAsyncObservable<TSource>.From(
source,
duration,
static async (source, duration, observer) =>
{
var (sourceObserver, timer) = await AsyncObserver.Take(observer, duration).ConfigureAwait(false);
var subscription = await source.SubscribeSafeAsync(sourceObserver).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, timer);View on GitHub (pinned to 94b5d5ab91)