{"record":{"id":"b9ef3474540633e5","repo":"dotnet/reactive","slug":"subscriptions","errorCode":null,"errorMessage":"subscriptions","messagePattern":"subscriptions","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupJoin.cs","lineNumber":52,"sourceCode":"                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\n    public partial class AsyncObserver\n    {\n        public static (IAsyncObserver<TLeft>, IAsyncObserver<TRight>, IAsyncDisposable) GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(IAsyncObserver<TResult> observer, IAsyncDisposable subscriptions, Func<TLeft, IAsyncObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IAsyncObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IAsyncObservable<TRight>, TResult> resultSelector)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (subscriptions == null)\n                throw new ArgumentNullException(nameof(subscriptions));\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            var gate = new AsyncGate();\n\n            var group = new CompositeAsyncDisposable(subscriptions);\n            var refCount = new RefCountAsyncDisposable(group);\n\n            var leftMap = new SortedDictionary<int, IAsyncObserver<TRight>>();\n            var rightMap = new SortedDictionary<int, TRight>();\n\n            var leftId = default(int);\n            var rightId = default(int);\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupJoin.cs#L34-L70","documentation":"AsyncObserver.GroupJoin throws ArgumentNullException when the subscriptions composite disposable is null. The subscriptions container tracks all duration-observable subscriptions so they can be disposed when either source completes; a null value would leak or crash the join logic. This is an internal invariant enforced by a fail-fast guard.","triggerScenarios":"Calling AsyncObserver.GroupJoin with null as the second (IAsyncDisposable subscriptions) argument — typically from custom operator code that forgot to construct the CompositeAsyncDisposable before delegating.","commonSituations":"Hand-rolled GroupJoin-like operators; unit tests calling the factory directly; code refactors where disposable creation moved after the factory call.","solutions":["Construct a CompositeAsyncDisposable and pass it as the subscriptions argument.","Follow the pattern in GroupJoin.cs: create `var subscriptions = new CompositeAsyncDisposable();` before calling AsyncObserver.GroupJoin.","If wrapping, never forward a null disposable — throw your own descriptive exception earlier."],"exampleFix":"// before\nvar (l, r, d) = AsyncObserver.GroupJoin(observer, null, ld, rd, rs);\n// after\nvar subscriptions = new CompositeAsyncDisposable();\nvar (l, r, d) = AsyncObserver.GroupJoin(observer, subscriptions, ld, rd, rs);","handlingStrategy":"validation","validationCode":"if (subscriptions == null) subscriptions = new CompositeAsyncDisposable();","typeGuard":"bool HasSubscriptions(IAsyncDisposable d) => d is not null;","tryCatchPattern":"try { var parts = AsyncObserver.GroupJoin(observer, subs, ld, rd, rs); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"subscriptions\") { /* construct CompositeAsyncDisposable and retry */ }","preventionTips":["Always create the CompositeAsyncDisposable before calling AsyncObserver.GroupJoin","Follow the exact pattern in GroupJoin.cs's public operator","Treat disposables as required constructor dependencies, never optional"],"tags":["argument-null","disposable","internal-api"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}