dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'third')
Error message
Value cannot be null. (Parameter 'third')
What it means
The three-source tuple overload of Zip throws ArgumentNullException when the third observable sequence is null. All three sequences must be subscribable; a null third argument is rejected before the query is built. The exception parameter name ('third') identifies the offending argument.
Solutions
- Initialize the third observable before zipping.
- Substitute Observable.Empty<TThird>() or Observable.Never<TThird>() when absence is legitimate.
- Guard the composition function with null checks that throw descriptive exceptions.
Example fix
// before var zipped = Observable.Zip(xs, ys, zs); // zs is null // after var zipped = Observable.Zip(xs, ys, zs ?? Observable.Empty<int>());
Defensive patterns
Strategy: validation
Validate before calling
if (third == null) throw new ArgumentNullException(nameof(third)); var zipped = Observable.Zip(first, second, third);
Type guard
bool IsSet<T>(IObservable<T> s) => s is not null;
Try / catch
try { var zipped = Observable.Zip(first, second, third); }
catch (ArgumentNullException ex) when (ex.ParamName == "third") { /* handle missing third source */ } Prevention
- Model optional streams as Observable.Never<T>() instead of null.
- Fail fast in factories: throw on creation failure instead of returning null.
- Add Debug.Assert / contract checks on source parameters in pipeline builders.
When it happens
Trigger: Calling Observable.Zip(first, second, null) with the (TFirst, TSecond, TThird) overload.
Common situations: Third source comes from a late-bound provider (signal generator, sensor feed, third API) whose factory returned null; optional feature stream not wired up.
Related errors
- Value cannot be null. (Parameter 'second')
- Value cannot be null. (Parameter 'fourth')
- null (Parameter 'scheduler')
- null (Parameter 'values')
- Value cannot be null. (Parameter 'observer')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/25c3bbf412c3d553.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:1223
/// <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>
/// <param name="first">First observable source.</param>
/// <param name="second">Second observable source.</param>
/// <param name="third">Third observable source.</param>
/// <returns>An observable sequence containing the result of combining elements of the sources using tuple values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="third"/> is null.</exception>
public static IObservable<(TFirst First, TSecond Second, TThird Third)> Zip<TFirst, TSecond, TThird>(this IObservable<TFirst> first, IObservable<TSecond> second, IObservable<TThird> third)
{
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
throw new ArgumentNullException(nameof(second));
if (third == null)
throw new ArgumentNullException(nameof(third));
return s_impl.Zip(first, second, third);
}
/// <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>
/// <param name="first">First observable source.</param>
/// <param name="second">Second observable source.</param>
/// <param name="third">Third observable source.</param>
/// <param name="fourth">Fourth observable source.</param>
/// <returns>An observable sequence containing the result of combining elements of the sources using tuple values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> or <paramref name="third"/> or <paramref name="fourth"/> is null.</exception>
public static IObservable<(TFirst First, TSecond Second, TThird Third, TFourth Fourth)> Zip<TFirst, TSecond, TThird, TFourth>(this IObservable<TFirst> first, IObservable<TSecond> second, IObservable<TThird> third, IObservable<TFourth> fourth)View on GitHub (pinned to 94b5d5ab91)