{"record":{"id":"4a9a8b17fcef3dc4","repo":"dotnet/reactive","slug":"resultselector","errorCode":null,"errorMessage":"resultSelector","messagePattern":"resultSelector","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupJoin.cs","lineNumber":26,"sourceCode":"using System.Threading;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TResult> GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(this IAsyncObservable<TLeft> left, IAsyncObservable<TRight> right, Func<TLeft, IAsyncObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IAsyncObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IAsyncObservable<TRight>, TResult> resultSelector)\n        {\n            if (left == null)\n                throw new ArgumentNullException(nameof(left));\n            if (right == null)\n                throw new ArgumentNullException(nameof(right));\n            if (leftDurationSelector == null)\n                throw new ArgumentNullException(nameof(leftDurationSelector));\n            if (rightDurationSelector == null)\n                throw new ArgumentNullException(nameof(rightDurationSelector));\n            if (resultSelector == null)\n                throw new ArgumentNullException(nameof(resultSelector));\n\n            return Create<TResult>(async observer =>\n            {\n                var subscriptions = new CompositeAsyncDisposable();\n\n                var (leftObserver, rightObserver, disposable) = AsyncObserver.GroupJoin(observer, subscriptions, leftDurationSelector, rightDurationSelector, resultSelector);\n\n                var leftSubscription = await left.SubscribeSafeAsync(leftObserver).ConfigureAwait(false);\n                await subscriptions.AddAsync(leftSubscription).ConfigureAwait(false);\n\n                var rightSubscription = await right.SubscribeSafeAsync(rightObserver).ConfigureAwait(false);\n                await subscriptions.AddAsync(rightSubscription).ConfigureAwait(false);\n\n                return disposable;\n            });\n        }\n    }\n","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupJoin.cs#L8-L44","documentation":"GroupJoin validates every delegate argument before doing any work and throws ArgumentNullException when the resultSelector delegate is null. The resultSelector combines each left value with the matching right observable into the final result, so the operator cannot proceed without it. This fail-fast guard surfaces the programming mistake at the call site instead of failing later inside the subscription.","triggerScenarios":"Calling AsyncObservable.GroupJoin(left, right, leftDurationSelector, rightDurationSelector, resultSelector) with a null fifth argument, e.g. passing an uninitialized Func<TLeft, IAsyncObservable<TRight>, TResult> or a misordered argument list that shifts null into the resultSelector position.","commonSituations":"Builders that assemble operator arguments from nullable configuration or DI-resolved delegates; refactors that changed the selector signature leaving a stale null lambda; conditional logic that assigns the selector only in some branches.","solutions":["Pass a non-null resultSelector delegate that maps (TLeft, IAsyncObservable<TRight>) to TResult.","Check argument order — ensure the lambda lands in the fifth parameter position, not shifted by a missing duration selector.","If the selector is conditionally supplied, default it to a valid fallback function before calling GroupJoin."],"exampleFix":"// before\nvar joined = AsyncObservable.GroupJoin(left, right, ld, rd, (Func<Left, IObservable<Right>, Result>)null);\n// after\nvar joined = AsyncObservable.GroupJoin(left, right, ld, rd, (l, rObs) => new Result(l, rObs));","handlingStrategy":"validation","validationCode":"if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));\n// or coerce: resultSelector ??= (l, rObs) => Result.Default(l, rObs);","typeGuard":"bool HasResultSelector(Func<L, IAsyncObservable<R>, T> f) => f is not null;","tryCatchPattern":"try { var joined = AsyncObservable.GroupJoin(left, right, ld, rd, resultSelector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"resultSelector\") { /* supply default selector and retry */ }","preventionTips":["Never assign delegates to nullable Func fields without a default","Verify positional argument order when calling 5-parameter operators","Let the compiler infer lambdas inline rather than declaring typed Func variables initialized to null"],"tags":["argument-null","argument-validation","rx-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"}