dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'fourteenth')

Error message

Value cannot be null. (Parameter 'fourteenth')

What it means

System.Reactive validates all fifteen observable source arguments of this Zip overload before constructing the query. A null fourteenth sequence trips the guard at Observable.Multiple.Zip.cs:1809, throwing ArgumentNullException with Parameter 'fourteenth'. The throw happens synchronously at call time so invalid compositions never reach subscription.

Solutions

  1. Supply a non-null IObservable<T> for the fourteenth source; use Observable.Empty<TFourteenth>() when absent by design.
  2. Validate/coalesce every source argument before calling Zip.
  3. Fix the upstream initialization that produced the null fourteenth stream.
  4. Prefer the IEnumerable overload of Zip for a dynamic number of sources.
  5. Catch ArgumentNullException around the composition to convert it into a domain error.

Example fix

// before
var q = s1.Zip(s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15); // s14 == null
// after
if (s14 is null) s14 = Observable.Empty<T14>();
var q = s1.Zip(s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15);
Defensive patterns

Strategy: validation

Validate before calling

if (s14 is null) s14 = Observable.Empty<T14>();

Type guard

static IObservable<T> NonNull<T>(IObservable<T>? s, [CallerArgumentExpression(nameof(s))] string? name = null) => s ?? throw new ArgumentNullException(name);

Try / catch

try { q = s1.Zip(..., s15); }
catch (ArgumentNullException ex) when (ex.ParamName == "fourteenth") { q = Fallback(); }

Prevention

When it happens

Trigger: Calling the public static Observable.Zip overload for up to fifteen IObservable<T> sources with null in the fourteenth argument position, i.e. immediately before the terminating s_impl.Zip(first, ..., fifteenth) call.

Common situations: A feed service returning null when unavailable; positional args to a 15-source zip where one source was conditionally created; hand-unrolled code from a dynamic sources list with fewer than 15 entries.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:1809

                throw new ArgumentNullException(nameof(fifth));
            if (sixth == null)
                throw new ArgumentNullException(nameof(sixth));
            if (seventh == null)
                throw new ArgumentNullException(nameof(seventh));
            if (eighth == null)
                throw new ArgumentNullException(nameof(eighth));
            if (ninth == null)
                throw new ArgumentNullException(nameof(ninth));
            if (tenth == null)
                throw new ArgumentNullException(nameof(tenth));
            if (eleventh == null)
                throw new ArgumentNullException(nameof(eleventh));
            if (twelfth == null)
                throw new ArgumentNullException(nameof(twelfth));
            if (thirteenth == null)
                throw new ArgumentNullException(nameof(thirteenth));
            if (fourteenth == null)
                throw new ArgumentNullException(nameof(fourteenth));
            if (fifteenth == null)
                throw new ArgumentNullException(nameof(fifteenth));

            return s_impl.Zip(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth, fifteenth);
        }

        /// <summary>
        /// Merges the specified observable sequences into one observable sequence of tuple values whenever all of the observable sequences have produced an element at a corresponding index.
        /// </summary>
        /// <typeparam name="TFirst">The type of the elements in the first source sequence.</typeparam>
        /// <typeparam name="TSecond">The type of the elements in the second source sequence.</typeparam>
        /// <typeparam name="TThird">The type of the elements in the third source sequence.</typeparam>
        /// <typeparam name="TFourth">The type of the elements in the fourth source sequence.</typeparam>
        /// <typeparam name="TFifth">The type of the elements in the fifth source sequence.</typeparam>
        /// <typeparam name="TSixth">The type of the elements in the sixth source sequence.</typeparam>
        /// <typeparam name="TSeventh">The type of the elements in the seventh source sequence.</typeparam>
        /// <typeparam name="TEighth">The type of the elements in the eighth source sequence.</typeparam>
        /// <typeparam name="TNinth">The type of the elements in the ninth source sequence.</typeparam>

View on GitHub (pinned to 94b5d5ab91)