{"record":{"id":"25c3bbf412c3d553","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-third-observable-multiple-zip","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'third')","messagePattern":"Value cannot be null\\. \\(Parameter 'third'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs","lineNumber":1223,"sourceCode":"        /// <summary>\n        /// Merges the specified observable sequences into one observable sequence of tuple values whenever all of the observable sequences have produced an element at a corresponding index.\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\"><paramref name=\"first\"/> or <paramref name=\"second\"/> or <paramref name=\"third\"/> is null.</exception>\n        public static IObservable<(TFirst First, TSecond Second, TThird Third)> Zip<TFirst, TSecond, TThird>(this IObservable<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 s_impl.Zip(first, second, third);\n        }\n\n        /// <summary>\n        /// Merges the specified observable sequences into one observable sequence of tuple values whenever all of the observable sequences have produced an element at a corresponding index.\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        /// <typeparam name=\"TFourth\">The type of the elements in the fourth 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        /// <param name=\"fourth\">Fourth 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\"><paramref name=\"first\"/> or <paramref name=\"second\"/> or <paramref name=\"third\"/> or <paramref name=\"fourth\"/> is null.</exception>\n        public static IObservable<(TFirst First, TSecond Second, TThird Third, TFourth Fourth)> Zip<TFirst, TSecond, TThird, TFourth>(this IObservable<TFirst> first, IObservable<TSecond> second, IObservable<TThird> third, IObservable<TFourth> fourth)","sourceCodeStart":1205,"sourceCodeEnd":1241,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs#L1205-L1241","documentation":"The three-source tuple overload of Zip throws ArgumentNullException when the third observable sequence is null. All three sequences must be subscribable; a null third argument is rejected before the query is built. The exception parameter name ('third') identifies the offending argument.","triggerScenarios":"Calling Observable.Zip(first, second, null) with the (TFirst, TSecond, TThird) overload.","commonSituations":"Third source comes from a late-bound provider (signal generator, sensor feed, third API) whose factory returned null; optional feature stream not wired up.","solutions":["Initialize the third observable before zipping.","Substitute Observable.Empty<TThird>() or Observable.Never<TThird>() when absence is legitimate.","Guard the composition function with null checks that throw descriptive exceptions."],"exampleFix":"// before\nvar zipped = Observable.Zip(xs, ys, zs); // zs is null\n// after\nvar zipped = Observable.Zip(xs, ys, zs ?? Observable.Empty<int>());","handlingStrategy":"validation","validationCode":"if (third == null) throw new ArgumentNullException(nameof(third));\nvar zipped = Observable.Zip(first, second, third);","typeGuard":"bool IsSet<T>(IObservable<T> s) => s is not null;","tryCatchPattern":"try { var zipped = Observable.Zip(first, second, third); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"third\") { /* handle missing third source */ }","preventionTips":["Model optional streams as Observable.Never<T>() instead of null.","Fail fast in factories: throw on creation failure instead of returning null.","Add Debug.Assert / contract checks on source parameters in pipeline builders."],"tags":["reactive","argument-null","zip"],"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"}