dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source5')
Error message
Value cannot be null. (Parameter 'source5')
What it means
The same 7-source Zip overload validates its arguments in order and throws ArgumentNullException when the 5th source observable is null. Zip needs every participating sequence, so a null in any slot aborts operator construction before subscription.
Solutions
- Supply a non-null IAsyncObservable for source5, or use AsyncObservable.Empty<T5>() when it can legitimately be absent.
- Add an up-front null check or require-non-null helper for each source before invoking Zip.
- Refactor to a lower-arity Zip overload or a Merge-based composition if one input is truly optional.
Example fix
// before
var zipped = AsyncObservable.Zip(a, b, c, d, fifthOrNull, f, g);
// after
if (fifthOrNull == null) throw new InvalidOperationException("fifth source missing");
var zipped = AsyncObservable.Zip(a, b, c, d, fifthOrNull, f, g); Defensive patterns
Strategy: validation
Validate before calling
var sources = new[] { s1, s2, s3, s4, s5, s6, s7 };
if (sources.Any(s => s == null)) throw new InvalidOperationException("all seven zip sources must be non-null"); Type guard
bool IsValidZipInput<T>(IAsyncObservable<T> s) => s is not null;
Try / catch
try
{
var zipped = AsyncObservable.Zip(s1, s2, s3, s4, s5, s6, s7);
}
catch (ArgumentNullException ex) when (ex.ParamName == "source5")
{
logger.LogError(ex, "5th zip source was null");
} Prevention
- Never let stream-producing factories return null; return AsyncObservable.Empty<T>() on miss
- Check nullable annotations on every feed before composing
- Write unit tests covering each source slot of multi-way zips
When it happens
Trigger: Calling AsyncObservable.Zip(source1, source2, source3, source4, null, source6, source7) with a null fifth IAsyncObservable argument.
Common situations: The fifth stream comes from a nullable return value (e.g. a cache miss returning null instead of an empty observable); list/dictionary-driven wiring where one entry is missing; copy-pasted zip calls after a source was renamed and left uninitialized.
Related errors
- Value cannot be null. (Parameter 'source4')
- Value cannot be null. (Parameter 'source6')
- Value cannot be null. (Parameter 'source7')
- Value cannot be null. (Parameter 'selector')
- Value cannot be null. (Parameter 'source1')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/a54f5530b90bd3e1.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Zip.Generated.cs:502
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);
var sub1 = source1.SubscribeSafeAsync(observer1).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
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();View on GitHub (pinned to 94b5d5ab91)