dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source9')
Error message
Value cannot be null. (Parameter 'source9')
What it means
The 9-source Zip overload checks source9 at Observable.Multiple.Zip.cs:413; a null ninth observable throws ArgumentNullException with Parameter 'source9'. Like the other guards, it fires synchronously at the Zip call, giving fail-fast diagnostics before the query ever runs.
Solutions
- Pass a valid IObservable for source9; substitute Observable.Empty<TSource9>() when the source can legitimately be missing.
- Repair the producing method so it returns an empty observable instead of null.
- Add a null-check/normalization step for all sources before composing.
- Reconsider arity: if sources are frequently optional, compose from a list of sources or use a different combinator that tolerates absence.
Example fix
// before var z = Observable.Zip(a, b, c, d, e, f, g, h, lastStream, sel); // lastStream == null // after var z = Observable.Zip(a, b, c, d, e, f, g, h, lastStream ?? Observable.Empty<T9>(), sel);
Defensive patterns
Strategy: validation
Validate before calling
if (source9 == null)
source9 = Observable.Empty<TSource9>(); Type guard
static bool Bound<T>(IObservable<T>? s) => s is not null;
Try / catch
try
{
var z = Observable.Zip(source1, source2, source3, source4, source5, source6, source7, source8, source9, selector);
}
catch (ArgumentNullException ex) when (ex.ParamName == "source9")
{
z = Observable.Empty<TResult>();
} Prevention
- When adding a new source to a Zip chain, update every environment/wiring site at once.
- Apply a uniform null-to-empty normalization to the whole source list before Zip.
- Enable nullable reference types so the final IObservable argument can't be silently null.
- Add a construction-time test per composition so Rx's eager guards run in CI.
When it happens
Trigger: Passing null as the ninth (final sequence) IObservable argument of the 9-argument Observable.Zip, e.g. an unassigned field or null returned by a stream factory.
Common situations: Nine-source aggregations where the last feed is newly added and not wired in all environments; partial test stubs; feature-flagged streams disabled leaving a null in the final position.
Related errors
- Value cannot be null. (Parameter 'fifth')
- nameof(onError)
- nameof(onCompleted)
- nameof(witness)
- Value cannot be null. (Parameter 'source9')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/56357e88fdde272c.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:413
if (source6 == null)
{
throw new ArgumentNullException(nameof(source6));
}
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 (resultSelector == null)
{
throw new ArgumentNullException(nameof(resultSelector));
}
return s_impl.Zip(source1, source2, source3, source4, source5, source6, source7, source8, source9, 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)