dotnet/reactive · error · ArgumentNullException

second

Error message

second

What it means

QbservableEx.CombineLatest<TFirst,TSecond> throws ArgumentNullException when the second (IObservable) source is null. Both inputs are combined element-wise into tuples inside the query expression, so a null second sequence cannot be represented and is rejected immediately.

Solutions

  1. Ensure the second observable is instantiated (e.g. Observable.FromEventPattern, Subject, or another factory).
  2. Null-check both inputs before combining; for an optional stream use second ?? Observable.Never<TSecond>().
  3. Fix the upstream factory or DI registration that returned a null observable.

Example fix

// before
IObservable<string> second = null;
var combined = first.CombineLatest(second);
// after
IObservable<string> second = otherStream ?? Observable.Never<string>();
var combined = first.CombineLatest(second);
Defensive patterns

Strategy: validation

Validate before calling

if (first is null || second is null) throw new InvalidOperationException("CombineLatest requires non-null first and second sources.");

Try / catch

try { var combined = first.CombineLatest(second); }
catch (ArgumentNullException ex) when (ex.ParamName == "second") { /* instantiate the second observable */ }

Prevention

When it happens

Trigger: Calling first.CombineLatest(null) or passing an IObservable<TSecond> variable that was never initialized; event streams or sensor observables that failed to be created upstream.

Common situations: Wiring UI or telemetry streams where one stream's factory returned null; optional streams not replaced by Observable.Never/Empty; DI misconfiguration leaving a stream dependency unset.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/QbservableEx.Homoicon.cs:37

{
    public static partial class QbservableEx
    {
        /// <summary>
        /// Merges the specified observable sequences into one observable sequence of tuple values whenever any of the observable sequences produces an element.
        /// </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>
        /// <param name="first">First observable source.</param>
        /// <param name="second">Second 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" /> is null.</exception>
        public static IQbservable<(TFirst First, TSecond Second)> CombineLatest<TFirst, TSecond>(this IQbservable<TFirst> first, IObservable<TSecond> second)
        {
            if (first == null)
                throw new ArgumentNullException(nameof(first));
            if (second == null)
                throw new ArgumentNullException(nameof(second));

            return first.Provider.CreateQuery<(TFirst First, TSecond Second)>(
                Expression.Call(
                    null,
                    new Func<IQbservable<TFirst>, IObservable<TSecond>, IQbservable<(TFirst First, TSecond Second)>>(CombineLatest<TFirst, TSecond>).Method,
                    first.Expression,
                    GetSourceExpression(second)
                )
            );
        }

        /// <summary>
        /// Merges the specified observable sequences into one observable sequence of tuple values whenever any of the observable sequences produces an element.
        /// </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>

View on GitHub (pinned to 94b5d5ab91)