dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'fourth')

Error message

Value cannot be null. (Parameter 'fourth')

What it means

The four-source tuple overload of Zip throws ArgumentNullException when the fourth observable sequence is null. This is fail-fast argument validation performed before the internal Zip implementation is instantiated, because a null sequence cannot be subscribed to. Parameter name 'fourth' identifies the missing source.

Solutions

  1. Initialize the fourth observable before the call.
  2. Substitute Observable.Empty<TFourth>() or Observable.Never<TFourth>() when absence is intended.
  3. Null-check all sources at the composition boundary and throw a descriptive error.

Example fix

// before
var zipped = Observable.Zip(xs, ys, zs, ws); // ws is null
// after
var zipped = Observable.Zip(xs, ys, zs, ws ?? Observable.Empty<int>());
Defensive patterns

Strategy: validation

Validate before calling

if (fourth == null) throw new ArgumentNullException(nameof(fourth));
var zipped = Observable.Zip(first, second, third, fourth);

Type guard

bool IsSet<T>(IObservable<T> s) => s is not null;

Try / catch

try { var zipped = Observable.Zip(first, second, third, fourth); }
catch (ArgumentNullException ex) when (ex.ParamName == "fourth") { /* treat fourth as empty */ }

Prevention

When it happens

Trigger: Calling Observable.Zip(first, second, third, null) with the four-tuple overload.

Common situations: Fourth stream from an optional telemetry or metrics source that is disabled and represented as null instead of an empty observable.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/be95410099927397. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:1250

        /// <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)
        {
            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));

            return s_impl.Zip(first, second, third, fourth);
        }

        /// <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>
        /// <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>
        /// <param name="fifth">Fifth observable source.</param>
        /// <returns>An observable sequence containing the result of combining elements of the sources using tuple values.</returns>

View on GitHub (pinned to 94b5d5ab91)