dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'fifteenth')
Error message
Value cannot be null. (Parameter 'fifteenth')
What it means
The fifteen-source Zip overload ends its argument validation with a null check on the fifteenth observable sequence, throwing ArgumentNullException at Observable.Multiple.Zip.cs:1811 if it is null. System.Reactive throws eagerly so the composed query is guaranteed to have a valid source in every position.
Solutions
- Pass a valid IObservable<T> as the fifteenth argument, or substitute Observable.Empty<TFifteenth>().
- Null-check/coalesce all fifteen source variables before composing.
- Fix the producer of the fifteenth sequence so it never returns null.
- Use the IEnumerable-based Zip overload when source count is dynamic.
- Wrap composition in try/catch (ArgumentNullException) with context about the missing source.
Example fix
// before var zipped = ZipAll(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15); // s15 == null // after var zipped = ZipAll(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15 ?? Observable.Empty<T15>());
Defensive patterns
Strategy: validation
Validate before calling
if (s15 is null) s15 = Observable.Empty<T15>();
Type guard
static IObservable<T> OrEmpty<T>(IObservable<T>? s) => s ?? Observable.Empty<T>();
Try / catch
try { zipped = ZipAll(s1, ..., s15); }
catch (ArgumentNullException ex) when (ex.ParamName == "fifteenth") { zipped = Observable.Empty<(T1,...,T15)>(); } Prevention
- When dropping or adding a source in a 15-arity call, update all positions and re-validate.
- Build argument lists programmatically from a validated collection to avoid short lists.
- Substitute Observable.Empty for trailing optional streams.
- Add a regression test that composes with every source non-null.
When it happens
Trigger: Calling the public static Observable.Zip overload taking up to fifteen IObservable<T> sources with null in the fifteenth (last) argument position, right before s_impl.Zip(first, ..., fifteenth) is invoked.
Common situations: A trailing optional stream left as null after a code change; building the argument list from a collection that is one element short; copy-paste edits that dropped the final source initializer.
Related errors
- Value cannot be null. (Parameter 'twelfth')
- Value cannot be null. (Parameter 'thirteenth')
- Value cannot be null. (Parameter 'fourteenth')
- Value cannot be null. (Parameter 'source10')
- Value cannot be null. (Parameter 'tenth')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/7c5f3ce8cf1a9ecb.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:1811
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>
/// <typeparam name="TTenth">The type of the elements in the tenth source sequence.</typeparam>
/// <typeparam name="TEleventh">The type of the elements in the eleventh source sequence.</typeparam>View on GitHub (pinned to 94b5d5ab91)