dotnet/reactive · error · ArgumentNullException
left
Error message
left
What it means
QueryableExtensions.And(left, right) combines an IQbservable left pattern with a right observable into a QueryablePattern; both operands must be non-null. The method throws ArgumentNullException("left") when the left IQbservable<TLeft> is null. Because this is the queryable (expression-tree) variant, the null check happens locally before the Expression.Call is built — a null left cannot be translated.
Solutions
- Ensure the left query is produced by a real IQbservableProvider (e.g. provider.CreateQuery) rather than null.
- Substitute an empty queryable sequence when the left side has no data.
- Null-check the left query before composing the And pattern.
Example fix
// before IQbservable<int> left = GetLeftQuery(); // null var pattern = left.And(right); // after IQbservable<int> left = GetLeftQuery() ?? provider.CreateQuery<int>(Observable.Empty<int>()); var pattern = left.And(right);
Defensive patterns
Strategy: validation
Validate before calling
if (left is null) throw new InvalidOperationException("left query must be created by an IQbservableProvider");
var pattern = left.And(right); Type guard
bool HasLeftQuery<TL, TR>(IQbservable<TL>? l, IObservable<TR>? r) => l is not null && r is not null;
Try / catch
try { var pattern = left.And(right); }
catch (ArgumentNullException ex) when (ex.ParamName == "left") { /* rebuild left via provider.CreateQuery before retrying */ } Prevention
- Only obtain IQbservable instances from a provider's CreateQuery
- Never let query-chain helpers return null; return empty queries
- Check nullable-reference-type warnings in query composition code
When it happens
Trigger: Calling left.And(right) where left is a null IQbservable<TLeft>, e.g. chaining off a query provider method that returned null.
Common situations: Building join patterns in IQbservable-based (e.g. Rx over remote/IQbservableProvider) pipelines where an earlier query step returned null instead of an empty sequence.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/48d6452f4e751052.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Qbservable.Joins.cs:29
{
public static partial class Qbservable
{
/* NOTE: Keep XML docs consistent with the corresponding Observable methods (modulo the IQbservableProvider parameters of course). */
/// <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>View on GitHub (pinned to 94b5d5ab91)