dotnet/reactive · error · ArgumentNullException
right
Error message
right
What it means
And(left, right) requires the right-hand IObservable<TRight> to be non-null; the method throws ArgumentNullException("right") before building the Expression.Call that embeds the And call into the queryable expression tree. The right sequence is a plain IObservable operand of the pattern, and a null reference cannot be represented in the expression.
Solutions
- Pass a valid IObservable<TRight>, e.g. Observable.Empty<TRight>() as a safe placeholder.
- Initialize/await the right-hand stream before composing the And pattern.
- Guard with a null check and skip pattern construction if the right stream is unavailable.
Example fix
// before var pattern = left.And(rightStream); // rightStream == null // after var pattern = left.And(rightStream ?? Observable.Empty<TRight>());
Defensive patterns
Strategy: validation
Validate before calling
if (right is null) right = Observable.Empty<TRight>(); var pattern = left.And(right);
Type guard
bool HasRightStream<TR>(IObservable<TR>? r) => r is not null;
Try / catch
try { var pattern = left.And(right); }
catch (ArgumentNullException ex) when (ex.ParamName == "right") { var pattern = left.And(Observable.Empty<TRight>()); } Prevention
- Initialize secondary streams before composing join patterns
- Use empty-observable placeholders when a stream is temporarily absent
- Assert non-null on streams received from external services
When it happens
Trigger: Calling left.And(null) or passing a right-hand observable variable that is null, commonly obtained from a failed lookup or uninitialized field.
Common situations: Composing patterns where the second stream comes from another service or event hookup that has not been initialized yet.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/180de826f4dc7fbc.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Qbservable.Joins.cs:34
/// <summary>
/// Creates a pattern that matches when both observable sequences have an available element.
/// </summary>
/// <typeparam name="TLeft">The type of the elements in the left sequence.</typeparam>
/// <typeparam name="TRight">The type of the elements in the right sequence.</typeparam>
/// <param name="left">Observable sequence to match with the right sequence.</param>
/// <param name="right">Observable sequence to match with the left sequence.</param>
/// <returns>Pattern object that matches when both observable sequences have an available element.</returns>
/// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is null.</exception>
public static QueryablePattern<TLeft, TRight> And<TLeft, TRight>(this IQbservable<TLeft> left, IObservable<TRight> right)
{
if (left == null)
{
throw new ArgumentNullException(nameof(left));
}
if (right == null)
{
throw new ArgumentNullException(nameof(right));
}
return new QueryablePattern<TLeft, TRight>(
Expression.Call(
null,
new Func<IQbservable<TLeft>, IObservable<TRight>, QueryablePattern<TLeft, TRight>>(And).Method,
left.Expression,
GetSourceExpression(right)
)
);
}
/// <summary>
/// Matches when the observable sequence has an available element and projects the element by invoking the selector function.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
/// <param name="source">Observable sequence to apply the selector on.</param>View on GitHub (pinned to 94b5d5ab91)