{"record":{"id":"f396d97e00cc29a6","repo":"dotnet/reactive","slug":"argumentnullexception-source","errorCode":null,"errorMessage":"ArgumentNullException: source","messagePattern":"ArgumentNullException: source","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs","lineNumber":77,"sourceCode":"            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\n            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TElement>>.From(\n                source,\n                (keySelector, elementSelector),\n                static (source, state, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, state.keySelector, state.elementSelector)));\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, 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 (elementSelector == null)","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs#L59-L95","documentation":"The GroupBy(source, keySelector, elementSelector) overload requires a non-null source observable. The library validates arguments eagerly at call time and throws ArgumentNullException naming the offending parameter instead of failing later inside the subscription pipeline. This is standard defensive argument checking consistent with System.Reactive conventions.","triggerScenarios":"Calling GroupBy and passing null as the source IAsyncObservable<TSource>, e.g. GroupBy(null, x => x.Key, x => x.Value) or when a preceding LINQ chain/variable returned null.","commonSituations":"Chaining operators on a variable that was never assigned; methods returning null instead of an empty observable; refactoring that removed the source expression; passing the result of a dictionary lookup that missed.","solutions":["Ensure the observable passed as source is non-null before calling GroupBy","Check upstream factory/repository methods so they return Observable.Empty rather than null","Add a null check or throw a meaningful domain-specific exception at the call site"],"exampleFix":"// before\nvar grouped = source?.GroupBy(x => x.Id, x => x.Data);\n// after\nif (source == null) throw new InvalidOperationException(\"source was not initialized\");\nvar grouped = source.GroupBy(x => x.Id, x => x.Data);","handlingStrategy":"validation","validationCode":"if (source == null) throw new ArgumentNullException(nameof(source));","typeGuard":"bool IsValidSource<TSource>(IAsyncObservable<TSource> s) => s is not null;","tryCatchPattern":"try { var g = source.GroupBy(k, e); } catch (ArgumentNullException ex) when (ex.ParamName == \"source\") { /* recover: rebuild observable */ }","preventionTips":["Never return null observables from factory methods; return an empty observable","Enable nullable reference types (#nullable enable) so null flows are caught at compile time","Assert non-null inputs at pipeline construction boundaries"],"tags":["argument-null","validation","linq","async-reactive"],"backgroundTag":"null-argument","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"}