{"record":{"id":"267160c9e0a69334","repo":"dotnet/reactive","slug":"argumentoutofrangeexception-capacity","errorCode":null,"errorMessage":"ArgumentOutOfRangeException: capacity","messagePattern":"ArgumentOutOfRangeException: capacity","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs","lineNumber":64,"sourceCode":"            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (capacity < 0)\n                throw new ArgumentOutOfRangeException(nameof(capacity));\n\n            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(\n                source,\n                (keySelector, capacity),\n                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.capacity)));\n        }\n\n        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, int capacity, IEqualityComparer<TKey> comparer)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (capacity < 0)\n                throw new ArgumentOutOfRangeException(nameof(capacity));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(\n                source,\n                (keySelector, capacity, comparer),\n                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.capacity, state.comparer)));\n        }\n\n        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (elementSelector == null)\n                throw new ArgumentNullException(nameof(elementSelector));\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs#L46-L82","documentation":"GroupBy(source, keySelector, capacity, comparer) throws ArgumentOutOfRangeException named 'capacity' when capacity is negative. The capacity parameter presets group storage and must be >= 0; the check runs before comparer validation and pipeline creation.","triggerScenarios":"Calling GroupBy(source, keySelector, negativeCapacity, comparer) — capacity parsed from config as -1 sentinel, computed from empty collections, or an int field defaulting to -1.","commonSituations":"Configuration with placeholder negative values; arithmetic underflow from Count - 1 on empty sequences; API defaults conflated with 'unset' sentinels.","solutions":["Clamp to non-negative: Math.Max(0, capacity) before the call.","Correct the configuration/computation producing the negative value.","Use the overload without capacity when no sizing hint is needed."],"exampleFix":"// before\nvar groups = source.GroupBy(x => x.Key, settings.GroupCapacity, comparer); // -1 possible\n// after\nvar capacity = settings.GroupCapacity < 0 ? 0 : settings.GroupCapacity;\nvar groups = source.GroupBy(x => x.Key, capacity, comparer);","handlingStrategy":"validation","validationCode":"if (capacity < 0) throw new InvalidOperationException(\"capacity must be >= 0\");\nvar safeCapacity = Math.Max(0, capacity);","typeGuard":"static bool IsValidCapacity(int capacity) => capacity >= 0;","tryCatchPattern":"try { var groups = source.GroupBy(keySelector, capacity, comparer); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"capacity\") { log.LogError(ex, \"GroupBy capacity was negative\"); throw; }","preventionTips":["Validate capacity at config-load time, not at pipeline-build time.","Use Math.Clamp or Math.Max for values parsed from settings.","Reserve 0 for 'no hint' instead of negative sentinels."],"tags":["argument-out-of-range","linq","argument-validation"],"backgroundTag":"value-out-of-range","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}