dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source10')
Error message
Value cannot be null. (Parameter 'source10')
What it means
System.Reactive's 10-argument Zip overload validates every argument eagerly when the public Zip method is called. Passing a null IObservable for the tenth source sequence causes an ArgumentNullException with Parameter 'source10' to be thrown immediately, before any subscription occurs. This fail-fast contract ensures invalid usage is caught at the call site rather than deep inside a subscription pipeline.
Solutions
- Ensure the tenth argument passed to Zip is a non-null IObservable; initialize it before the Zip call.
- If the source may legitimately be absent, substitute Observable.Empty<TSource10>() or a default sequence instead of null.
- Check where the tenth sequence is produced (a prior Rx operator or factory) and fix whatever returns null - Rx operators themselves never return null.
- Wrap configuration/resolution of the sources in null checks before composing the query.
Example fix
// before IObservable<int> source10 = condition ? obsA : null; var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, source10, (a,b,c,d,e,f,g,h,i,j) => a); // after IObservable<int> source10 = condition ? obsA : Observable.Empty<int>(); var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, source10, (a,b,c,d,e,f,g,h,i,j) => a);
Defensive patterns
Strategy: validation
Validate before calling
if (source1 == null) throw new InvalidOperationException("source1 must be provided"); // ...repeat for sources 2-9
if (source10 == null)
{
source10 = Observable.Empty<TSource10>(); // or fix initialization
} Type guard
bool IsValidSource<T>(IObservable<T> s) => s is not null;
// usage: if (sources.All(IsValidSource)) { /* call Zip */ } Try / catch
try
{
var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, selector);
}
catch (ArgumentNullException ex) when (ex.ParamName == "source10")
{
// log which argument was null and repair initialization
} Prevention
- Never assign null to an IObservable field; prefer Observable.Empty<T>() as the empty default.
- Validate the whole sources collection before composing: sources.All(s => s != null).
- Avoid operator results being nullable - Rx operators always return non-null, so a null sequence indicates external code.
When it happens
Trigger: Calling Observable.Zip(source1..source9, source10, resultSelector) (the 10-source overload in Observable.Multiple.Zip.cs) where the tenth IObservable<TSource10> argument is null.
Common situations: Chaining Zip calls where an earlier operator returned null; holding sequences in nullable fields/properties that were never initialized; wiring up sources from a dictionary or service locator where the tenth entry is missing.
Related errors
- ArgumentNullException(nameof(source))
- ArgumentNullException(nameof(other))
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'onNext')
- Value cannot be null. (Parameter 'onError')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/07a0652c64d3ed3e.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:500
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 (resultSelector == null)
{
throw new ArgumentNullException(nameof(resultSelector));
}
return s_impl.Zip(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, 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)