dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'source3')

Error message

Value cannot be null. (Parameter 'source3')

What it means

ArgumentNullException thrown by the generated 7-source Zip operator because source3 (the third IAsyncObservable) is null. Zip pairs elements positionally across all seven sequences, so every source must be a valid observable instance.

Solutions

  1. Supply a non-null third observable or AsyncObservable.Empty<T3>() as a placeholder
  2. Check construction of each source in the pipeline for one returning null
  3. Confirm no arguments were skipped/shifted in the 8-argument call

Example fix

// before
var zipped = s1.Zip(s2, s3, s4, s5, s6, s7, sel); // s3 == null
// after
var s3Fixed = s3 ?? AsyncObservable.Empty<T3>();
var zipped = s1.Zip(s2, s3Fixed, s4, s5, s6, s7, sel);
Defensive patterns

Strategy: validation

Validate before calling

if (source3 is null) throw new InvalidOperationException("Zip requires all source observables; source3 was null.");
if (new[] { s1, s2, s3, s4, s5, s6, s7 }.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")
{
    throw new InvalidOperationException($"Zip input missing: {ex.ParamName}", ex);
}

Prevention

When it happens

Trigger: Calling s1.Zip(s2, null, s4, s5, s6, s7, selector) with a null third source; also occurs when a dynamically built source list has a gap at index 2.

Common situations: Optional third stream not initialized; a data-driven pipeline where one input stream failed to construct; copy-paste of Zip argument lists missing one source.

Related errors


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

Appendix: source

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

                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);

                var sub1 = source1.SubscribeSafeAsync(observer1).AsTask().ContinueWith(disposable => d.AddAsync(disposable.Result).AsTask()).Unwrap();

View on GitHub (pinned to 94b5d5ab91)