dotnet/reactive · error · ArgumentNullException
source10
Error message
source10
What it means
System.ArgumentNullException thrown by the public Zip overload combining 14 observable sources in Observable.Multiple.Zip.cs when the tenth source sequence (source10) is null. Rx.NET's Zip operator requires every input sequence to be a live, non-null IObservable<TSource> because it must subscribe to each one to pair elements across sequences. Passing null violates the library's eager null-check contract, so it fails fast at call time instead of inside the subscription pipeline.
Solutions
- Ensure the tenth argument passed to Zip is a real observable; construct or await it before the call.
- If the stream is intentionally empty, pass Observable.Empty<T>() instead of null.
- Guard with ArgumentNullException.ThrowIfNull(s10) / a null check before invoking Zip so the failure surfaces at your own call site with a clearer message.
- If sources come from a collection, replace the 14-argument overload with Observable.Zip(sources, resultSelector) over a non-empty, null-free list.
Example fix
// before var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, (a, b, c, d, e, f, g, h, i, j, k, l, m, n) => j); // after ArgumentNullException.ThrowIfNull(s10); var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 ?? Observable.Empty<TimeSpan>(), s11, s12, s13, s14, (a, b, c, d, e, f, g, h, i, j, k, l, m, n) => j);
Defensive patterns
Strategy: validation
Validate before calling
if (s10 is null) throw new ArgumentNullException(nameof(s10));
Type guard
static bool IsValidSource<T>(IObservable<T>? s) => s is not null;
Try / catch
try { var zipped = Observable.Zip(s1, ..., s10, ..., s14, selector); } catch (ArgumentNullException ex) when (ex.ParamName == "source10") { // substitute Observable.Empty<T>() and retry } Prevention
- Never pass nullable observable fields straight into Zip; normalize them to Observable.Empty<T>() first.
- Validate all 14 sources with a helper loop before composing.
- Prefer the collection-based Zip overload so null slots are checkable in one place.
- Enable nullable reference types (NRT) so the compiler flags potential nulls at the call site.
When it happens
Trigger: Calling the 14-source Observable.Zip overload, e.g. Observable.Zip(s1, s2, ..., s10, ..., s14, resultSelector), with s10 (the tenth argument) being a null IObservable reference while the other arguments are non-null observables and resultSelector is non-null.
Common situations: Building a fixed-size array of streams where one slot was never initialized (e.g. sources[9] left null after conditional population); refactoring code that replaced a placeholder observable with null instead of Observable.Empty<T>(); DI or factory methods returning null for one of several merged event streams; copying a call site and forgetting to update one of the positional arguments.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/0315b91c7fae3e1a.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:898
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));
}
if (source13 == null)
{
throw new ArgumentNullException(nameof(source13));
}
if (source14 == null)View on GitHub (pinned to 94b5d5ab91)