{"record":{"id":"be95410099927397","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-fourth-observable-multiple","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'fourth')","messagePattern":"Value cannot be null\\. \\(Parameter 'fourth'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs","lineNumber":1250,"sourceCode":"        /// <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)\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            if (fourth == null)\n                throw new ArgumentNullException(nameof(fourth));\n\n            return s_impl.Zip(first, second, third, fourth);\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        /// <typeparam name=\"TFifth\">The type of the elements in the fifth 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        /// <param name=\"fifth\">Fifth observable source.</param>\n        /// <returns>An observable sequence containing the result of combining elements of the sources using tuple values.</returns>","sourceCodeStart":1232,"sourceCodeEnd":1268,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs#L1232-L1268","documentation":"The four-source tuple overload of Zip throws ArgumentNullException when the fourth observable sequence is null. This is fail-fast argument validation performed before the internal Zip implementation is instantiated, because a null sequence cannot be subscribed to. Parameter name 'fourth' identifies the missing source.","triggerScenarios":"Calling Observable.Zip(first, second, third, null) with the four-tuple overload.","commonSituations":"Fourth stream from an optional telemetry or metrics source that is disabled and represented as null instead of an empty observable.","solutions":["Initialize the fourth observable before the call.","Substitute Observable.Empty<TFourth>() or Observable.Never<TFourth>() when absence is intended.","Null-check all sources at the composition boundary and throw a descriptive error."],"exampleFix":"// before\nvar zipped = Observable.Zip(xs, ys, zs, ws); // ws is null\n// after\nvar zipped = Observable.Zip(xs, ys, zs, ws ?? Observable.Empty<int>());","handlingStrategy":"validation","validationCode":"if (fourth == null) throw new ArgumentNullException(nameof(fourth));\nvar zipped = Observable.Zip(first, second, third, fourth);","typeGuard":"bool IsSet<T>(IObservable<T> s) => s is not null;","tryCatchPattern":"try { var zipped = Observable.Zip(first, second, third, fourth); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"fourth\") { /* treat fourth as empty */ }","preventionTips":["Represent disabled telemetry/metric streams with Observable.Empty, not null.","Null-check each argument at the composition boundary.","Adopt nullable reference types to catch unassigned stream fields at compile time."],"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"}