{"record":{"id":"f1699f2608fa1cb4","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-right-observable","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'right')","messagePattern":"Value cannot be null\\. \\(Parameter 'right'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.StandardSequenceOperators.cs","lineNumber":851,"sourceCode":"        /// <typeparam name=\"TRightDuration\">The type of the elements in the duration sequence denoting the computed duration of each element in the right source sequence.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence, obtained by invoking the result selector function for source elements with overlapping duration.</typeparam>\n        /// <param name=\"left\">The left observable sequence to join elements for.</param>\n        /// <param name=\"right\">The right observable sequence to join elements for.</param>\n        /// <param name=\"leftDurationSelector\">A function to select the duration of each element of the left observable sequence, used to determine overlap.</param>\n        /// <param name=\"rightDurationSelector\">A function to select the duration of each element of the right observable sequence, used to determine overlap.</param>\n        /// <param name=\"resultSelector\">A function invoked to compute a result element for any element of the left sequence with overlapping elements from the right observable sequence.</param>\n        /// <returns>An observable sequence that contains result elements computed from source elements that have an overlapping duration.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"left\"/> or <paramref name=\"right\"/> or <paramref name=\"leftDurationSelector\"/> or <paramref name=\"rightDurationSelector\"/> or <paramref name=\"resultSelector\"/> is null.</exception>\n        public static IObservable<TResult> GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(this IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IObservable<TRight>, TResult> resultSelector)\n        {\n            if (left == null)\n            {\n                throw new ArgumentNullException(nameof(left));\n            }\n\n            if (right == null)\n            {\n                throw new ArgumentNullException(nameof(right));\n            }\n\n            if (leftDurationSelector == null)\n            {\n                throw new ArgumentNullException(nameof(leftDurationSelector));\n            }\n\n            if (rightDurationSelector == null)\n            {\n                throw new ArgumentNullException(nameof(rightDurationSelector));\n            }\n\n            if (resultSelector == null)\n            {\n                throw new ArgumentNullException(nameof(resultSelector));\n            }\n\n            return s_impl.GroupJoin(left, right, leftDurationSelector, rightDurationSelector, resultSelector);","sourceCodeStart":833,"sourceCodeEnd":869,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.StandardSequenceOperators.cs#L833-L869","documentation":"ArgumentNullException guard in Observable.GroupJoin: the 'right' observable sequence to join against the left sequence was null. Windowed joins require both duration-bearing sequences, so the null right argument is rejected at query construction time.","triggerScenarios":"Calling left.GroupJoin(null, leftDurationSelector, rightDurationSelector, resultSelector) — usually a right stream resolved from a nullable source or a failed lookup.","commonSituations":"Inner stream coming from a cache/registry that returned null; optional inner streams modeled as null; DI wiring where the right stream registration was missing.","solutions":["Ensure the right observable is created/registered before the join.","Substitute Observable.Empty<TRight>() when no right source exists.","Null-check before the call and surface a message naming the missing stream."],"exampleFix":"// before\nvar joined = left.GroupJoin(_rightStream, ...); // _rightStream not yet set\n// after\nvar right = _rightStream ?? Observable.Empty<Right>();\nvar joined = left.GroupJoin(right, ...);","handlingStrategy":"validation","validationCode":"if (right == null)\n    throw new InvalidOperationException(\"Right observable for GroupJoin was not registered.\");","typeGuard":"bool HasRight<T>(IObservable<T>? s) => s is not null;","tryCatchPattern":"try\n{\n    var joined = left.GroupJoin(right, ld, rd, rs);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"right\")\n{\n    // register or fall back to Observable.Empty<TRight>()\n}","preventionTips":["Register inner/right streams in DI before any join is constructed.","Have cache/registry lookups return Observable.Empty instead of null.","Assert stream fields are initialized in startup validation."],"tags":["null-argument","linq","reactive-extensions","groupjoin"],"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"}