dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'eighth')
Error message
Value cannot be null. (Parameter 'eighth')
What it means
The 8-source Zip overload throws ArgumentNullException when the eighth (last) sequence argument is null. Every source passed to Zip must be a valid observable because the operator subscribes to all of them to combine elements pairwise by index. The check is performed synchronously in the public method before returning the zipped sequence.
Solutions
- Supply a valid observable for the eighth argument
- If the eighth source is optional, pass Observable.Empty<T>() so Zip completes immediately per its semantics
- Fix the factory/lookup that produced null to return a non-null sequence
- Add a pre-call validation loop over the sources with named failure messages
Example fix
// before var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, last); // last is null // after var last = lastStream ?? Observable.Empty<int>(); var zipped = Observable.Zip(s1, s2, s3, s4, s5, s6, s7, last);
Defensive patterns
Strategy: validation
Validate before calling
if (eighth is null) throw new ArgumentNullException(nameof(eighth));
// or: if (new[] { first, second, third, fourth, fifth, sixth, seventh, eighth }.Any(s => s is null)) throw new InvalidOperationException("Zip source is null"); Type guard
static bool IsNonNull<T>(IObservable<T>? s) => s is not null;
Try / catch
try { var zipped = Observable.Zip(a, b, c, d, e, f, g, h); }
catch (ArgumentNullException ex) when (ex.ParamName == "eighth") { /* supply Observable.Empty or log */ } Prevention
- When extending a Zip to more sources, add the new stream explicitly, never a placeholder
- Use Observable.Empty<T>() as the canonical 'absent' source
- Turn on nullable reference types and treat IObservable<T>? warnings as errors
- Centralize multi-stream composition in one validated helper method
When it happens
Trigger: Calling Observable.Zip(first, second, third, fourth, fifth, sixth, seventh, eighth) with the eighth IObservable<T> argument null — e.g. a truncated argument list from a refactor, or a variable holding the result of a null-returning factory.
Common situations: Extending an existing 7-way Zip to 8 sources and forgetting the last one; one stream in a fixed pipeline is conditionally created and was null at runtime; copy-paste left a placeholder unassigned.
Related errors
- Value cannot be null. (Parameter 'source9')
- nameof(removeHandler)
- nameof(target)
- nameof(eventName)
- observer
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/47c5e9df6e6a8655.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:1398
/// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="third"/> or <paramref name="fourth"/> or <paramref name="fifth"/> or <paramref name="sixth"/> or <paramref name="seventh"/> or <paramref name="eighth"/> is null.</exception>
public static IObservable<(TFirst First, TSecond Second, TThird Third, TFourth Fourth, TFifth Fifth, TSixth Sixth, TSeventh Seventh, TEighth Eighth)> Zip<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth>(this IObservable<TFirst> first, IObservable<TSecond> second, IObservable<TThird> third, IObservable<TFourth> fourth, IObservable<TFifth> fifth, IObservable<TSixth> sixth, IObservable<TSeventh> seventh, IObservable<TEighth> eighth)
{
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
throw new ArgumentNullException(nameof(second));
if (third == null)
throw new ArgumentNullException(nameof(third));
if (fourth == null)
throw new ArgumentNullException(nameof(fourth));
if (fifth == null)
throw new ArgumentNullException(nameof(fifth));
if (sixth == null)
throw new ArgumentNullException(nameof(sixth));
if (seventh == null)
throw new ArgumentNullException(nameof(seventh));
if (eighth == null)
throw new ArgumentNullException(nameof(eighth));
return s_impl.Zip(first, second, third, fourth, fifth, sixth, seventh, eighth);
}
/// <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>
/// <param name="first">First observable source.</param>
/// <param name="second">Second observable source.</param>View on GitHub (pinned to 94b5d5ab91)