dotnet/reactive · error · ArgumentNullException
source
Error message
source
What it means
Then(source, selector) creates a QueryablePlan from a pattern source and an expression-tree selector; both must be non-null. The method throws ArgumentNullException("source") when the IQbservable<TSource> is null. The check runs before the Expression.Call for the Then operator is constructed, since a null source cannot appear in a valid queryable expression.
Solutions
- Ensure the source pattern comes from a valid IQbservableProvider chain ending in And/Then.
- Substitute an empty queryable sequence if the source legitimately has no data.
- Null-check the source before calling Then.
Example fix
// before var plan = source.Then(x => x * 2); // source == null // after var plan = (source ?? provider.CreateQuery<int>(Observable.Empty<int>())).Then(x => x * 2);
Defensive patterns
Strategy: validation
Validate before calling
if (source is null) throw new InvalidOperationException("Then requires a non-null IQbservable source");
var plan = source.Then(selector); Type guard
bool HasPatternSource<TS>(IQbservable<TS>? s) => s is not null;
Try / catch
try { var plan = source.Then(proj); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* rebuild the pattern source from the provider */ } Prevention
- Build Then plans only from provider-created queryables
- Verify each chain step returns non-null before the next
- Keep join-plan construction in one place with null assertions
When it happens
Trigger: Calling source.Then(selector) on a null IQbservable<TSource>, typically a pattern stage produced by a provider method that returned null.
Common situations: Building When/Then join plans where an earlier And/chain step yielded null instead of a queryable sequence.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/123b33df01fa0542.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Qbservable.Joins.cs:60
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>
/// <param name="selector">Selector that will be invoked for elements in the source sequence.</param>
/// <returns>Plan that produces the projected results, to be fed (with other plans) to the When operator.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
public static QueryablePlan<TResult> Then<TSource, TResult>(this IQbservable<TSource> source, Expression<Func<TSource, TResult>> selector)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (selector == null)
{
throw new ArgumentNullException(nameof(selector));
}
return new QueryablePlan<TResult>(
Expression.Call(
null,
new Func<IQbservable<TSource>, Expression<Func<TSource, TResult>>, QueryablePlan<TResult>>(Then).Method,
source.Expression,
selector
)
);
}
/// <summary>View on GitHub (pinned to 94b5d5ab91)