dotnet/reactive · error · ArgumentOutOfRangeException

new ArgumentOutOfRangeException(nameof(capacity))

Error message

new ArgumentOutOfRangeException(nameof(capacity))

What it means

GroupBy(source, keySelector, capacity) throws ArgumentOutOfRangeException when capacity is negative. Capacity presets the internal storage for groups; a negative value is meaningless and is rejected up front. Zero is accepted.

Solutions

  1. Pass a non-negative capacity; clamp with Math.Max(0, capacity).
  2. Fix the config/source of the capacity value so it is >= 0.
  3. If capacity is optional, use the two-argument GroupBy overload instead of passing -1.

Example fix

// before
var groups = source.GroupBy(x => x.Key, config.BufferSize); // may be -1
// after
var groups = source.GroupBy(x => x.Key, Math.Max(0, config.BufferSize));
Defensive patterns

Strategy: validation

Validate before calling

if (capacity < 0) throw new InvalidOperationException("capacity must be >= 0");
var safeCapacity = Math.Max(0, capacity);

Type guard

static bool IsValidCapacity(int capacity) => capacity >= 0;

Try / catch

try { var groups = source.GroupBy(keySelector, capacity); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "capacity") { log.LogError(ex, "GroupBy capacity was negative"); throw; }

Prevention

When it happens

Trigger: Calling GroupBy(source, keySelector, capacity) with capacity < 0 — typically capacity read from config (e.g. '-1' parsed to int), computed as count-1 when the collection is empty, or a default sentinel like -1 meaning 'unset'.

Common situations: Config files with negative or placeholder capacity values; arithmetic like items.Count - 1 on empty input; sentinel -1 used for 'auto' but not supported by this API.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs:49

            if (keySelector == null)
                throw new ArgumentNullException(nameof(keySelector));
            if (comparer == null)
                throw new ArgumentNullException(nameof(comparer));

            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(
                source,
                (keySelector, comparer),
                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.comparer)));
        }

        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, int capacity)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (keySelector == null)
                throw new ArgumentNullException(nameof(keySelector));
            if (capacity < 0)
                throw new ArgumentOutOfRangeException(nameof(capacity));

            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(
                source,
                (keySelector, capacity),
                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.capacity)));
        }

        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, int capacity, IEqualityComparer<TKey> comparer)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (keySelector == null)
                throw new ArgumentNullException(nameof(keySelector));
            if (capacity < 0)
                throw new ArgumentOutOfRangeException(nameof(capacity));
            if (comparer == null)
                throw new ArgumentNullException(nameof(comparer));

View on GitHub (pinned to 94b5d5ab91)