{"record":{"id":"989b6b5b4936c46e","repo":"dotnet/reactive","slug":"new-argumentnullexception-nameof-source-groupby","errorCode":null,"errorMessage":"new ArgumentNullException(nameof(source))","messagePattern":"new ArgumentNullException\\(nameof\\(source\\)\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs","lineNumber":17,"sourceCode":"﻿// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT License.\n// See the LICENSE file in the project root for more information. \n\nusing System.Collections.Generic;\nusing System.Reactive.Disposables;\nusing System.Reactive.Subjects;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n\n            return CreateAsyncObservable<IGroupedAsyncObservable<TKey, TSource>>.From(\n                source,\n                keySelector,\n                static (source, keySelector, observer) => GroupByCore(source, observer, (o, d) => AsyncObserver.GroupBy(o, d, keySelector)));\n        }\n\n        public static IAsyncObservable<IGroupedAsyncObservable<TKey, TSource>> GroupBy<TSource, TKey>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, 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 (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupBy.cs#L1-L35","documentation":"GroupBy partitions an async observable into IGroupedAsyncObservable streams keyed by keySelector. The library validates the source first and throws ArgumentNullException(nameof(source)) when it is null, consistent with all operator entry points failing fast on null arguments.","triggerScenarios":"Calling source.GroupBy(keySelector) where source is null — typically the result of a chain or factory that produced null, or a nullable observable field read before assignment.","commonSituations":"Pipeline builders composing operators conditionally where one branch returns null; configuration-driven source selection missing a mapping; unit tests passing null to operator extension methods directly.","solutions":["Verify the upstream operator/factory call — library operators never return null, so find where null entered the chain.","Guard with a null check before calling GroupBy and surface a domain-specific error.","Enable nullable reference types so the null source is caught statically."],"exampleFix":"// before\nvar groups = maybeSource.GroupBy(x => x.Key);\n// after\nif (maybeSource == null) throw new InvalidOperationException(\"source missing\");\nvar groups = maybeSource.GroupBy(x => x.Key);","handlingStrategy":"validation","validationCode":"if (source is null) throw new InvalidOperationException(\"cannot group a null source\");","typeGuard":"static bool IsGroupable<TSource>(IAsyncObservable<TSource>? s) => s is not null;","tryCatchPattern":"try { var groups = source.GroupBy(keySelector); } catch (ArgumentNullException ex) when (ex.ParamName == \"source\") { /* fix upstream source creation */ }","preventionTips":["Audit pipeline builders for branches that can return null sources","Enable nullable reference types across operator chains","Throw domain errors instead of returning null from source factories"],"tags":["argument-null","null-check","groupby","operator"],"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"}