dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'source15')

Error message

Value cannot be null. (Parameter 'source15')

What it means

Same eager null validation in the 15-source Zip overload, triggered when the 15th (last) IAsyncObservable argument (source15) is null. The check runs before Create() builds the result observable, so the failure is synchronous at the call site.

Solutions

  1. Check the 15th argument is a non-null IAsyncObservable.
  2. Ensure the collection feeding Zip has exactly 15 non-null sources.
  3. Fix the producer of source15.
  4. Wrap the call in a validation helper that rejects null sources with a clear message.

Example fix

// before
AsyncObservable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15);
// after
if (s15 == null) throw new InvalidOperationException("source15 must be provided");
AsyncObservable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15);
Defensive patterns

Strategy: validation

Validate before calling

if (s15 is null) throw new InvalidOperationException("source15 must be provided before zipping");

Type guard

static bool IsNonNull<T>(IAsyncObservable<T> s) => s is not null;

Try / catch

try { var zipped = AsyncObservable.Zip(s1, ..., s15); }
catch (ArgumentNullException ex) when (ex.ParamName == "source15") { /* handle missing trailing stream */ }

Prevention

When it happens

Trigger: Calling AsyncObservable.Zip(source1..source15) with null in the 15th argument position.

Common situations: Trailing argument omitted or null after editing the call; a stream that exists only under certain feature flags; array of sources shorter than expected with implicit null fill.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/bdf85a21afda5802. Report an issue: GitHub.

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Zip.Generated.cs:1657

                throw new ArgumentNullException(nameof(source6));
            if (source7 == null)
                throw new ArgumentNullException(nameof(source7));
            if (source8 == null)
                throw new ArgumentNullException(nameof(source8));
            if (source9 == null)
                throw new ArgumentNullException(nameof(source9));
            if (source10 == null)
                throw new ArgumentNullException(nameof(source10));
            if (source11 == null)
                throw new ArgumentNullException(nameof(source11));
            if (source12 == null)
                throw new ArgumentNullException(nameof(source12));
            if (source13 == null)
                throw new ArgumentNullException(nameof(source13));
            if (source14 == null)
                throw new ArgumentNullException(nameof(source14));
            if (source15 == null)
                throw new ArgumentNullException(nameof(source15));

            return Create<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>(async observer =>
            {
                var d = new CompositeAsyncDisposable();

                var (observer1, observer2, observer3, observer4, observer5, observer6, observer7, observer8, observer9, observer10, observer11, observer12, observer13, observer14, observer15) = 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();
                var sub9 = source9.SubscribeSafeAsync(observer9).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
                var sub10 = source10.SubscribeSafeAsync(observer10).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();
                var sub11 = source11.SubscribeSafeAsync(observer11).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();

View on GitHub (pinned to 94b5d5ab91)