dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'source6')

Error message

Value cannot be null. (Parameter 'source6')

What it means

Rx.NET's CombineLatest<T1..T6,TResult> overload (Observable.Multiple.CombineLatest.cs:198) eagerly validates every argument when the public extension method is invoked, before any subscription happens. A null sixth source observable makes it impossible to subscribe or combine values, so the library throws ArgumentNullException with the parameter name 'source6' synchronously at call time rather than surfacing an error through the observable pipeline. This fail-fast contract is documented via <exception cref="ArgumentNullException"> on the method.

Solutions

  1. Ensure the sixth argument is a valid non-null IObservable<T> before calling CombineLatest (e.g. Observable.Empty<T>() or Observable.Never<T>() as a default).
  2. Coalesce with the null-coalescing operator: source6 ?? Observable.Empty<T6>().
  3. If the source may legitimately be absent, gate the CombineLatest call behind a null check or use a conditional expression to pick an alternative overload.

Example fix

// before
var combined = Observable.CombineLatest(s1, s2, s3, s4, s5, sources[5], (a,b,c,d,e,f) => f);
// after
var sixth = sources[5] ?? Observable.Empty<T6>();
var combined = Observable.CombineLatest(s1, s2, s3, s4, s5, sixth, (a,b,c,d,e,f) => f);
Defensive patterns

Strategy: validation

Validate before calling

if (source6 is null) throw new InvalidOperationException("source6 must be provided before combining");
// or default it: var s6 = source6 ?? Observable.Empty<T6>();

Type guard

static bool IsSourceValid<T>(IObservable<T>? s) => s is not null;

Try / catch

try { var combined = Observable.CombineLatest(s1, s2, s3, s4, s5, s6, sel); }
catch (ArgumentNullException ex) when (ex.ParamName == "source6") { Log.Warning("source6 missing; using empty stream"); combined = Observable.CombineLatest(s1, s2, s3, s4, s5, Observable.Empty<T6>(), sel); }

Prevention

When it happens

Trigger: Calling Observable.CombineLatest(source1..source5, source6, resultSelector) with the 6-source overload where source6 is null, e.g. a dictionary lookup, conditional, or optional field returned null for the sixth observable.

Common situations: Building observables from nullable configuration values where one entry is missing; passing results of a factory method that can return null; refactoring code that changed an array of sources into discrete parameters and one slot is unpopulated; tests wiring up 6 streams where one dependency failed to initialize.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.CombineLatest.cs:198

            if (source3 == null)
            {
                throw new ArgumentNullException(nameof(source3));
            }

            if (source4 == null)
            {
                throw new ArgumentNullException(nameof(source4));
            }

            if (source5 == null)
            {
                throw new ArgumentNullException(nameof(source5));
            }

            if (source6 == null)
            {
                throw new ArgumentNullException(nameof(source6));
            }

            if (resultSelector == null)
            {
                throw new ArgumentNullException(nameof(resultSelector));
            }

            return s_impl.CombineLatest(source1, source2, source3, source4, source5, source6, resultSelector);
        }

        /// <summary>
        /// Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.
        /// </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)