dotnet/reactive · error · ArgumentNullException
third
Error message
third
What it means
This ArgumentNullException is thrown by QbservableEx.CombineLatest<TFirst,TSecond,TThird> because the third source sequence was null. The Qbservable extensions eagerly validate all source arguments before building the expression tree via CreateQuery, since a null expression source cannot be represented in the IQueryable provider model. It is a fail-fast contract guard, not a runtime data error.
Solutions
- Pass a valid IObservable<TThird>, e.g. Observable.Empty<TThird>() or Observable.Never<TThird>() instead of null.
- Fix the producer of the third argument so it returns a non-null sequence.
- Add a null check / coalesce before calling CombineLatest.
Example fix
// before var combined = source.CombineLatest(a, b /* b is null */); // after var combined = source.CombineLatest(a, b ?? Observable.Empty<int>());
Defensive patterns
Strategy: validation
Validate before calling
if (first == null || second == null || third == null) throw new InvalidOperationException("CombineLatest sources must all be non-null; use Observable.Empty<T>() instead."); Type guard
static bool AllNonNull<T1, T2, T3>(T1 a, T2 b, T3 c) where T1 : class where T2 : class where T3 : class => a != null && b != null && c != null;
Try / catch
try { var combined = first.CombineLatest(second, third); } catch (ArgumentNullException ex) { logger.LogError(ex, "Null CombineLatest source: {Param}", ex.ParamName); } Prevention
- Never return null from observable factory methods; return Observable.Empty<T>() or Observable.Never<T>().
- Coalesce nullable stream variables with ?? Observable.Empty<T>() before combining.
- Enable nullable reference types (C# 8+) so null-flow is caught at compile time.
When it happens
Trigger: Calling CombineLatest(first, second, third) on IQbservable<TFirst> with third == null, e.g. passing the result of a method that returned null instead of an empty IObservable<TThird>.
Common situations: Chaining observable factories whose return values are not null-checked; refactoring Rx code to Qbservable code where a null 'no source' value previously slipped through; conditional pipelines where a later source is only assigned in some branches.
Related errors
- fourth
- fifth
- Value cannot be null. (Parameter 'third')
- Value cannot be null. (Parameter 'fourth')
- Value cannot be null. (Parameter 'fifth')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/3c1377acb859df27.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/QbservableEx.Homoicon.cs:68
/// 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>
/// <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 IQbservable<(TFirst First, TSecond Second, TThird Third)> CombineLatest<TFirst, TSecond, TThird>(this IQbservable<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 first.Provider.CreateQuery<(TFirst First, TSecond Second, TThird Third)>(
Expression.Call(
null,
new Func<IQbservable<TFirst>, IObservable<TSecond>, IObservable<TThird>, IQbservable<(TFirst First, TSecond Second, TThird Third)>>(CombineLatest<TFirst, TSecond, TThird>).Method,
first.Expression,
GetSourceExpression(second),
GetSourceExpression(third)
)
);
}
/// <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>View on GitHub (pinned to 94b5d5ab91)