{"record":{"id":"3c1377acb859df27","repo":"dotnet/reactive","slug":"third","errorCode":null,"errorMessage":"third","messagePattern":"third","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/QbservableEx.Homoicon.cs","lineNumber":68,"sourceCode":"        /// Merges the specified observable sequences into one observable sequence of tuple values whenever any of the observable sequences produces an element.\n        /// </summary>\n        /// <typeparam name=\"TFirst\">The type of the elements in the first source sequence.</typeparam>\n        /// <typeparam name=\"TSecond\">The type of the elements in the second source sequence.</typeparam>\n        /// <typeparam name=\"TThird\">The type of the elements in the third source sequence.</typeparam>\n        /// <param name=\"first\">First observable source.</param>\n        /// <param name=\"second\">Second observable source.</param>\n        /// <param name=\"third\">Third observable source.</param>\n        /// <returns>An observable sequence containing the result of combining elements of the sources using tuple values.</returns>\n        /// <exception cref=\"ArgumentNullException\">\n        /// <paramref name=\"first\" /> or <paramref name=\"second\" /> or <paramref name=\"third\" /> is null.</exception>\n        public static IQbservable<(TFirst First, TSecond Second, TThird Third)> CombineLatest<TFirst, TSecond, TThird>(this IQbservable<TFirst> first, IObservable<TSecond> second, IObservable<TThird> third)\n        {\n            if (first == null)\n                throw new ArgumentNullException(nameof(first));\n            if (second == null)\n                throw new ArgumentNullException(nameof(second));\n            if (third == null)\n                throw new ArgumentNullException(nameof(third));\n\n            return first.Provider.CreateQuery<(TFirst First, TSecond Second, TThird Third)>(\n                Expression.Call(\n                    null,\n                    new Func<IQbservable<TFirst>, IObservable<TSecond>, IObservable<TThird>, IQbservable<(TFirst First, TSecond Second, TThird Third)>>(CombineLatest<TFirst, TSecond, TThird>).Method,\n                    first.Expression,\n                    GetSourceExpression(second),\n                    GetSourceExpression(third)\n                )\n            );\n        }\n\n        /// <summary>\n        /// Merges the specified observable sequences into one observable sequence of tuple values whenever any of the observable sequences produces an element.\n        /// </summary>\n        /// <typeparam name=\"TFirst\">The type of the elements in the first source sequence.</typeparam>\n        /// <typeparam name=\"TSecond\">The type of the elements in the second source sequence.</typeparam>\n        /// <typeparam name=\"TThird\">The type of the elements in the third source sequence.</typeparam>","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/QbservableEx.Homoicon.cs#L50-L86","documentation":"This ArgumentNullException is thrown by QbservableEx.CombineLatest<TFirst,TSecond,TThird> because the third source sequence was null. The Qbservable extensions eagerly validate all source arguments before building the expression tree via CreateQuery, since a null expression source cannot be represented in the IQueryable provider model. It is a fail-fast contract guard, not a runtime data error.","triggerScenarios":"Calling CombineLatest(first, second, third) on IQbservable<TFirst> with third == null, e.g. passing the result of a method that returned null instead of an empty IObservable<TThird>.","commonSituations":"Chaining observable factories whose return values are not null-checked; refactoring Rx code to Qbservable code where a null 'no source' value previously slipped through; conditional pipelines where a later source is only assigned in some branches.","solutions":["Pass a valid IObservable<TThird>, e.g. Observable.Empty<TThird>() or Observable.Never<TThird>() instead of null.","Fix the producer of the third argument so it returns a non-null sequence.","Add a null check / coalesce before calling CombineLatest."],"exampleFix":"// before\nvar combined = source.CombineLatest(a, b /* b is null */);\n// after\nvar combined = source.CombineLatest(a, b ?? Observable.Empty<int>());","handlingStrategy":"validation","validationCode":"if (first == null || second == null || third == null) throw new InvalidOperationException(\"CombineLatest sources must all be non-null; use Observable.Empty<T>() instead.\");","typeGuard":"static bool AllNonNull<T1, T2, T3>(T1 a, T2 b, T3 c) where T1 : class where T2 : class where T3 : class => a != null && b != null && c != null;","tryCatchPattern":"try { var combined = first.CombineLatest(second, third); } catch (ArgumentNullException ex) { logger.LogError(ex, \"Null CombineLatest source: {Param}\", ex.ParamName); }","preventionTips":["Never return null from observable factory methods; return Observable.Empty<T>() or Observable.Never<T>().","Coalesce nullable stream variables with ?? Observable.Empty<T>() before combining.","Enable nullable reference types (C# 8+) so null-flow is caught at compile time."],"tags":["argumentnull","qbservable","combinelatest","reactive-extensions"],"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"}