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 'capacity')
What it means
The capacity parameter bounds how many groups may exist concurrently and must be non-negative. Passing a negative value throws ArgumentOutOfRangeException at GroupByUntil.cs:57. This is a fail-fast range check applied when the capacity overload is invoked.
Solutions
- Clamp the capacity before the call: Math.Max(0, computedCapacity)
- Fix the config/arithmetic source producing the negative value
- Validate user- or config-supplied capacity at load time and reject negatives early
Example fix
// before int capacity = config.MaxGroups - activeGroups; // can be negative var groups = source.GroupByUntil(x => x.Key, g => g.Take(1), capacity); // after int capacity = Math.Max(0, config.MaxGroups - activeGroups); var groups = source.GroupByUntil(x => x.Key, g => g.Take(1), capacity);
Defensive patterns
Strategy: validation
Validate before calling
if (capacity < 0) throw new ArgumentException("capacity must be >= 0"); // or clamp: capacity = Math.Max(0, capacity); Type guard
bool IsValidCapacity(int capacity) => capacity >= 0;
Try / catch
try { var groups = source.GroupByUntil(ks, ds, capacity); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "capacity") { capacity = 0; /* retry or log bad config */ } Prevention
- Clamp computed capacities with Math.Max(0, n)
- Validate capacity-bearing configuration at startup, not at call time
- Avoid -1 sentinels for 'unset' int fields feeding API arguments
When it happens
Trigger: Calling AsyncObservable.GroupByUntil(source, keySelector, durationSelector, -1) — typically a computed capacity like limit - consumed that went negative, or an uninitialized/default-initialized sentinel.
Common situations: Capacity derived from configuration where a negative or unparsed value slipped in; arithmetic like expectedCount - actualCount producing -1; int fields defaulted to -1 as 'unset'.
Related errors
- capacity
- nameof(index)
- Specified argument was out of the range of valid values…
- Value cannot be null. (Parameter 'keySelector')
- Value cannot be null. (Parameter 'durationSelector')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/8d7ab099cf54e6ca.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupByUntil.cs:57
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(
source,
(keySelector, durationSelector, comparer),
static (source, state, observer) => GroupByUntilCore<TSource, TKey, TSource, TDuration>(source, observer, (o, d) => AsyncObserver.GroupByUntil(o, d, state.keySelector, state.durationSelector, state.comparer)));
}
public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupByUntil<TSource, TKey, TDuration>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<IGroupedAsyncObservable<TKey, TSource>, IAsyncObservable<TDuration>> durationSelector, int capacity)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (durationSelector == null)
throw new ArgumentNullException(nameof(durationSelector));
if (capacity < 0)
throw new ArgumentOutOfRangeException(nameof(capacity));
return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(
source,
(keySelector, durationSelector, capacity),
static (source, state, observer) => GroupByUntilCore<TSource, TKey, TSource, TDuration>(source, observer, (o, d) => AsyncObserver.GroupByUntil(o, d, state.keySelector, state.durationSelector, state.capacity)));
}
public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupByUntil<TSource, TKey, TDuration>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<IGroupedAsyncObservable<TKey, TSource>, IAsyncObservable<TDuration>> durationSelector, int capacity, IEqualityComparer<TKey> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (durationSelector == null)
throw new ArgumentNullException(nameof(durationSelector));
if (capacity < 0)
throw new ArgumentOutOfRangeException(nameof(capacity));
if (comparer == null)View on GitHub (pinned to 94b5d5ab91)