dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'source12')

Error message

Value cannot be null. (Parameter 'source12')

What it means

ArgumentNullException thrown by the generated 12-ary Zip operator when the final source observable (source12) is null. The operator's validation block checks all twelve sources in order and this is the last check before it proceeds to build the zip via Create and AsyncObserver.Zip — meaning arguments 1-11 were valid and only the 12th was null.

Solutions

  1. Create or resolve the 12th source before the call; fix any null-returning producer.
  2. Pass AsyncObservable.Empty<T>() if the twelfth stream is genuinely optional.
  3. Reformat the call one-argument-per-line to make nulls visible in review.
  4. Add a guard clause or assertion in the composing method.

Example fix

// before
var zipped = AsyncObservable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, null);
// after
var s12 = CreateSource12();
var zipped = AsyncObservable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12);
Defensive patterns

Strategy: validation

Validate before calling

if (s12 == null) throw new InvalidOperationException("source12 must be provided before Zip");

Type guard

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

Try / catch

try { var zipped = AsyncObservable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12); }
catch (ArgumentNullException ex) when (ex.ParamName == "source12") { log.Error("source12 was null"); }

Prevention

When it happens

Trigger: AsyncObservable.Zip(s1..s12) invoked with a null 12th argument: a last parameter left null because it was considered 'optional', or a producer returning null on an error path.

Common situations: Trailing arguments in very long calls are the most frequently left null; appending a new stream to an existing Zip and forgetting to create it; test scaffolding that stubs only the first N sources.

Related errors


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

Appendix: source

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

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

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

                var (observer1, observer2, observer3, observer4, observer5, observer6, observer7, observer8, observer9, observer10, observer11, observer12) = 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)