{"record":{"id":"f2615dfc50769db3","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-source1-f2615d","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'source1')","messagePattern":"Value cannot be null\\. \\(Parameter 'source1'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs","lineNumber":28,"sourceCode":"    {\n        /// <summary>\n        /// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.\n        /// </summary>\n        /// <typeparam name=\"TSource1\">The type of the elements in the first source sequence.</typeparam>\n        /// <typeparam name=\"TSource2\">The type of the elements in the second source sequence.</typeparam>\n        /// <typeparam name=\"TSource3\">The type of the elements in the third source sequence.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence, returned by the selector function.</typeparam>\n        /// <param name=\"source1\">First observable source.</param>\n        /// <param name=\"source2\">Second observable source.</param>\n        /// <param name=\"source3\">Third observable source.</param>\n        /// <param name=\"resultSelector\">Function to invoke for each series of elements at corresponding indexes in the sources.</param>\n        /// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source1\"/> or <paramref name=\"source2\"/> or <paramref name=\"source3\"/> or <paramref name=\"resultSelector\"/> is null.</exception>\n        public static IObservable<TResult> Zip<TSource1, TSource2, TSource3, TResult>(this IObservable<TSource1> source1, IObservable<TSource2> source2, IObservable<TSource3> source3, Func<TSource1, TSource2, TSource3, TResult> resultSelector)\n        {\n            if (source1 == null)\n            {\n                throw new ArgumentNullException(nameof(source1));\n            }\n\n            if (source2 == null)\n            {\n                throw new ArgumentNullException(nameof(source2));\n            }\n\n            if (source3 == null)\n            {\n                throw new ArgumentNullException(nameof(source3));\n            }\n\n            if (resultSelector == null)\n            {\n                throw new ArgumentNullException(nameof(resultSelector));\n            }\n\n            return s_impl.Zip(source1, source2, source3, resultSelector);","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs#L10-L46","documentation":"The Observable.Zip overload for three sources plus a result selector throws ArgumentNullException when source1 is null. Rx validates all inputs eagerly at the public API boundary so misuses fail immediately instead of deep inside subscription. Supply a non-null IObservable as the first argument.","triggerScenarios":"Calling source1.Zip(source2, source3, resultSelector) or Observable.Zip(source1, source2, source3, resultSelector) with a null first sequence.","commonSituations":"A factory method returning null instead of a sequence; a dictionary/config lookup for the primary stream failing; wiring up streams in a DI container where the first binding is missing.","solutions":["Ensure the first observable passed to Zip is non-null.","Fall back to Observable.Empty<TSource1>() when the first source may legitimately be absent.","Add a null check or Debug.Assert on the primary stream before combining."],"exampleFix":"// before\nvar merged = maybeFirst.Zip(second, third, (a, b, c) => a + b + c); // maybeFirst is null\n// after\nvar merged = (maybeFirst ?? Observable.Empty<int>()).Zip(second, third, (a, b, c) => a + b + c);","handlingStrategy":"validation","validationCode":"if (source1 == null || source2 == null || source3 == null || resultSelector == null)\n    throw new InvalidOperationException(\"Zip requires non-null sources and selector\");","typeGuard":"bool IsValid<T>(IObservable<T> s) => s is not null;","tryCatchPattern":"try { return source1.Zip(source2, source3, resultSelector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"source1\") { /* log and use fallback sequence */ }","preventionTips":["Enable C# nullable reference types so null-flow bugs surface at compile time","Guard stream factories so they never return null","Check dictionary/config lookups for missing streams before zipping"],"tags":["null-argument","reactive-extensions","zip","argument-validation"],"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"}