dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source2')
Error message
Value cannot be null. (Parameter 'source2')
What it means
ArgumentNullException thrown by the generated 7-source Zip operator because source2 (the second IAsyncObservable) is null. The generated Zip overloads validate each source and the selector in order, so a null second source is reported with parameter name 'source2'.
Solutions
- Pass a valid second observable; substitute AsyncObservable.Empty<T2>() if 'no elements' is intended
- Check where source2 is produced/loaded (DI, array index, property init)
- Verify argument order in the long Zip call — a shifted argument list is a common cause
Example fix
// before var zipped = s1.Zip(streams[0], streams[1], streams[2], streams[3], streams[4], streams[5], sel); // streams[0] == null // after var s2 = streams[0] ?? AsyncObservable.Empty<T2>(); var zipped = s1.Zip(s2, streams[1], streams[2], streams[3], streams[4], streams[5], sel);
Defensive patterns
Strategy: validation
Validate before calling
if (source2 is null) throw new InvalidOperationException("Zip requires all source observables; source2 was null.");
var sources = new[] { s1, s2, s3, s4, s5, s6, s7 };
if (sources.Any(s => s is null)) throw new InvalidOperationException("All Zip sources must be non-null."); Type guard
bool AllNonNull<T>(params IAsyncObservable<T>?[] sources) => sources.All(s => s is not null);
Try / catch
try { var zipped = s1.Zip(s2, s3, s4, s5, s6, s7, selector); }
catch (ArgumentNullException ex) when (ex.ParamName is "source1" or "source2" or "source3" or "source4" or "source5" or "source6" or "source7")
{
// substitute empty observables for missing sources or surface pipeline misconfiguration
throw new InvalidOperationException($"Zip input missing: {ex.ParamName}", ex);
} Prevention
- Build long Zip calls from a validated list of sources, checking every element
- Replace optional streams with AsyncObservable.Empty<T>() rather than null
- Double-check argument order in generated/long operator signatures
When it happens
Trigger: Calling source1.Zip(s2, s3, s4, s5, s6, s7, selector) where the second argument is null — e.g. an array/field element that was never populated. Note source1 must also be non-null (checked first).
Common situations: Building the list of streams from a collection with missing entries; a nullable observable property not yet initialized; misordered arguments in a long call.
Related errors
- Value cannot be null. (Parameter 'source3')
- scheduler
- observer
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'onCompletedAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/5853b9dbe89b360d.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Zip.Generated.cs:496
var sub2 = source2.SubscribeSafeAsync(observer2).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
var sub3 = source3.SubscribeSafeAsync(observer3).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
var sub4 = source4.SubscribeSafeAsync(observer4).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
var sub5 = source5.SubscribeSafeAsync(observer5).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
var sub6 = source6.SubscribeSafeAsync(observer6).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
var sub7 = source7.SubscribeSafeAsync(observer7).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
await Task.WhenAll(sub1, sub2, sub3, sub4, sub5, sub6, sub7).ConfigureAwait(false);
return d;
});
}
public static IAsyncObservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, TResult>(this IAsyncObservable<T1> source1, IAsyncObservable<T2> source2, IAsyncObservable<T3> source3, IAsyncObservable<T4> source4, IAsyncObservable<T5> source5, IAsyncObservable<T6> source6, IAsyncObservable<T7> source7, Func<T1, T2, T3, T4, T5, T6, T7, TResult> selector)
{
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 (source4 == null)
throw new ArgumentNullException(nameof(source4));
if (source5 == null)
throw new ArgumentNullException(nameof(source5));
if (source6 == null)
throw new ArgumentNullException(nameof(source6));
if (source7 == null)
throw new ArgumentNullException(nameof(source7));
if (selector == null)
throw new ArgumentNullException(nameof(selector));
return Create<TResult>(async observer =>
{
var d = new CompositeAsyncDisposable();
var (observer1, observer2, observer3, observer4, observer5, observer6, observer7) = AsyncObserver.Zip(observer, selector);View on GitHub (pinned to 94b5d5ab91)