dotnet/reactive · error · ArgumentNullException
source15
Error message
source15
What it means
This ArgumentNullException is thrown synchronously by the public Zip extension method when the fifteenth source observable (source15) is null. Rx operators validate all arguments up front before subscribing, so a null source is rejected immediately rather than surfacing later as a NullReferenceException inside the query. The 15-source overload requires every input sequence to be a non-null IObservable<T>.
Solutions
- Ensure source15 is assigned a valid IObservable<TSource15> instance before calling Zip
- If 'no data' is intended, pass Observable.Empty<TSource15>() instead of null
- Guard the call site with a null check and throw a meaningful application-level error or use a default source
- If sources come from a collection, filter or validate entries with a null check before zipping
Example fix
// before var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, null, (a, b) => a + b); // after IObservable<int> s15 = GetFifteenthSource() ?? Observable.Empty<int>(); var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, (a, b) => a + b);
Defensive patterns
Strategy: validation
Validate before calling
if (source15 == null)
{
source15 = Observable.Empty<TSource15>(); // or throw a domain-specific error
}
var zipped = Observable.Zip(s1, ..., source15, resultSelector); Type guard
static bool IsValidSource<TSource15>(IObservable<TSource15> s) => s is not null;
Try / catch
try
{
var zipped = Observable.Zip(s1, ..., s15, selector);
return zipped;
}
catch (ArgumentNullException ex) when (ex.ParamName == nameof(source15))
{
// log which source was null and fall back to an empty/alternate pipeline
return Observable.Empty<TResult>();
} Prevention
- Never represent 'no stream' as null; use Observable.Empty<T>
- Have stream factories return non-null observables unconditionally
- Null-check or assert all sources before composing long Zip chains
- Prefer combining sources from a collection with a null filter before zipping
When it happens
Trigger: Calling Observable.Zip(source1..source14, null, resultSelector) - i.e. the 15-argument overload of Zip with source15 passed as null while all other arguments are non-null. The check executes synchronously at the Zip call site (Observable.Multiple.Zip.cs:1040).
Common situations: Building zip chains programmatically where one entry in a source array/collection is null; refactoring from a 14-source Zip to 15 sources and forgetting to wire the new source; a factory or DI method returning null instead of an empty observable; LINQ query syntax where an intermediate expression evaluates to null.
Related errors
- Value cannot be null. (Parameter 'source1')
- Value cannot be null. (Parameter 'source2')
- Value cannot be null. (Parameter 'resultSelector')
- Value cannot be null. (Parameter 'source13')
- Value cannot be null. (Parameter 'ninth')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/6f1c0e1bb2001b22.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:1040
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));
}
if (resultSelector == null)
{
throw new ArgumentNullException(nameof(resultSelector));
}
return s_impl.Zip(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector);
}
/// <summary>
/// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
/// </summary>
/// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
/// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
/// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
/// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
/// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>View on GitHub (pinned to 94b5d5ab91)