dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source8')
Error message
Value cannot be null. (Parameter 'source8')
What it means
AsyncRx.NET's 8-ary Zip operator validates every source before building the observable pipeline. Passing null for the eighth IAsyncObservable source causes an ArgumentNullException with Parameter 'source8'. The library fails fast at call time because a null source would otherwise break subscription logic deep inside AsyncObserver.Zip.
Solutions
- Initialize source8 to a valid IAsyncObservable<T8> before calling Zip (e.g. AsyncObservable.Empty<T8>()).
- Check the expression producing source8 for accidental null returns (failed lookups, uninitialized fields).
- Add a guard or default-substitute (?? AsyncObservable.Empty<T8>()) at the call site.
- If sources are in a collection, assert the collection has no null elements before spreading into Zip.
Example fix
// before var zipped = s1.Zip(s2, s3, s4, s5, s6, s7, lookup8, (a,b,c,d,e,f,g,h) => a+h); // after var s8 = lookup8 ?? AsyncObservable.Empty<T8>(); var zipped = s1.Zip(s2, s3, s4, s5, s6, s7, s8, (a,b,c,d,e,f,g,h) => a+h);
Defensive patterns
Strategy: validation
Validate before calling
if (source8 == null)
throw new InvalidOperationException("Zip requires a non-null source8");
// or default it: var s8 = maybeSource8 ?? AsyncObservable.Empty<T8>(); Type guard
static bool HasSource<T>(IAsyncObservable<T> s) => s is not null;
Try / catch
try
{
var zipped = s1.Zip(s2, s3, s4, s5, s6, s7, s8, selector);
}
catch (ArgumentNullException ex) when (ex.ParamName == "source8")
{
// fall back to empty-source pipeline or log configuration error
} Prevention
- Never let stream factories return null; return AsyncObservable.Empty instead
- Null-check all zipped sources in one guard helper before composing
- Cover multi-source wiring with unit tests that assert non-null observables
When it happens
Trigger: Calling source1.Zip(source2, ..., source8) where the eighth argument is null - e.g. a dictionary lookup, conditional expression, or method returning null was passed as source8.
Common situations: Building source lists dynamically (arrays or LINQ projections containing nulls), refactoring code where a source factory started returning null, or optional stream wiring where one of eight inputs was never initialized.
Related errors
- nameof(finallyAction)
- nameof(source)
- nameof(predicate)
- Argument cannot be null (Parameter name: observer)
- Value cannot be null. (Parameter 'gate')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/6780954af2ac5605.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Zip.Generated.cs:586
public static IAsyncObservable<(T1, T2, T3, T4, T5, T6, T7, T8)> Zip<T1, T2, T3, T4, T5, T6, T7, T8>(this IAsyncObservable<T1> source1, IAsyncObservable<T2> source2, IAsyncObservable<T3> source3, IAsyncObservable<T4> source4, IAsyncObservable<T5> source5, IAsyncObservable<T6> source6, IAsyncObservable<T7> source7, IAsyncObservable<T8> source8)
{
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 (source8 == null)
throw new ArgumentNullException(nameof(source8));
return Create<(T1, T2, T3, T4, T5, T6, T7, T8)>(async observer =>
{
var d = new CompositeAsyncDisposable();
var (observer1, observer2, observer3, observer4, observer5, observer6, observer7, observer8) = AsyncObserver.Zip(observer);
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();
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();
var sub8 = source8.SubscribeSafeAsync(observer8).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
await Task.WhenAll(sub1, sub2, sub3, sub4, sub5, sub6, sub7, sub8).ConfigureAwait(false);
View on GitHub (pinned to 94b5d5ab91)