dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source1')
Error message
Value cannot be null. (Parameter 'source1')
What it means
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.
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.
Example fix
// before var merged = maybeFirst.Zip(second, third, (a, b, c) => a + b + c); // maybeFirst is null // after var merged = (maybeFirst ?? Observable.Empty<int>()).Zip(second, third, (a, b, c) => a + b + c);
Defensive patterns
Strategy: validation
Validate before calling
if (source1 == null || source2 == null || source3 == null || resultSelector == null)
throw new InvalidOperationException("Zip requires non-null sources and selector"); Type guard
bool IsValid<T>(IObservable<T> s) => s is not null;
Try / catch
try { return source1.Zip(source2, source3, resultSelector); }
catch (ArgumentNullException ex) when (ex.ParamName == "source1") { /* log and use fallback sequence */ } Prevention
- 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
When it happens
Trigger: Calling source1.Zip(source2, source3, resultSelector) or Observable.Zip(source1, source2, source3, resultSelector) with a null first sequence.
Common situations: 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.
Related errors
- Value cannot be null. (Parameter 'source2')
- Value cannot be null. (Parameter 'resultSelector')
- source15
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'subscription')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/f2615dfc50769db3.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:28
{
/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
/// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
/// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
/// <param name="source1">First observable source.</param>
/// <param name="source2">Second observable source.</param>
/// <param name="source3">Third observable source.</param>
/// <param name="resultSelector">Function to invoke for each series of elements at corresponding indexes in the sources.</param>
/// <returns>An observable sequence containing the result of combining elements of the sources using the specified result selector function.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source1"/> or <paramref name="source2"/> or <paramref name="source3"/> or <paramref name="resultSelector"/> is null.</exception>
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)
{
if (source1 == null)
{
throw new ArgumentNullException(nameof(source1));
}
if (source2 == null)
{
throw new ArgumentNullException(nameof(source2));
}
if (source3 == null)
{
throw new ArgumentNullException(nameof(source3));
}
if (resultSelector == null)
{
throw new ArgumentNullException(nameof(resultSelector));
}
return s_impl.Zip(source1, source2, source3, resultSelector);View on GitHub (pinned to 94b5d5ab91)