dotnet/reactive · error · ArgumentNullException
predicate
Error message
predicate
What it means
System.Reactive's public Count overload that accepts a predicate throws ArgumentNullException because the predicate Func<TSource,bool> is null. The argument-guard block in Observable.Aggregates.cs:710 eagerly validates arguments before subscribing, so the failure is synchronous and deterministic rather than surfacing on the observable pipeline. This follows the Rx contract that all operator configuration arguments are validated at call time.
Solutions
- Pass a non-null predicate lambda, e.g. x => x.SomeCondition.
- If the predicate is optional, branch to the parameterless Count(source) overload instead of passing null.
- Null-check or coalesce the predicate before the call (predicate ?? (_ => true) if 'match all' is the intended behavior).
- Trace where the Func came from — a factory or config lookup returned null and should be fixed at its origin.
Example fix
// before
int count = await source.Count(predicate: config.Filter); // config.Filter is null
// after
int count = config.Filter != null
? await source.Count(config.Filter)
: await source.Count(); Defensive patterns
Strategy: validation
Validate before calling
if (source == null) throw new InvalidOperationException("source must not be null");
if (predicate == null) throw new InvalidOperationException("predicate must not be null before calling Count"); Type guard
bool CanCount<T>(IObservable<T>? source, Func<T, bool>? predicate) => source != null && predicate != null;
Try / catch
try { var count = await source.Count(pred); }
catch (ArgumentNullException ex) when (ex.ParamName == "predicate") { /* fall back to source.Count() */ } Prevention
- Never store predicates as nullable Func fields without initialization
- Branch to the parameterless overload instead of passing a null predicate
- Coalesce optional filters: predicate ?? (_ => true)
When it happens
Trigger: Calling Observable.Count(source, predicate) (the two-argument overload) with a null predicate, e.g. Observable.Count(xs, condition) where condition is the result of an unassigned variable, a failed factory method, or a ternary that resolved to null.
Common situations: Building query expressions dynamically where the predicate comes from optional configuration; refactoring code where a lambda was replaced by a nullable Func field that was never assigned; passing the result of a lookup into a dictionary of predicates that missed the key.
Related errors
- Value cannot be null. (Parameter 'source5')
- Value cannot be null. (Parameter 'gate')
- Value cannot be null. (Parameter 'asyncLock')
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'scheduler')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/448649d33e73b458.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs:710
/// <summary>
/// Returns an observable sequence containing an <see cref="int" /> that represents how many elements in the specified observable sequence satisfy a condition.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">An observable sequence that contains elements to be counted.</param>
/// <param name="predicate">A function to test each element for a condition.</param>
/// <returns>An observable sequence containing a single element with a number that represents how many elements in the input sequence satisfy the condition in the predicate function.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="predicate"/> is null.</exception>
/// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
public static IObservable<int> Count<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (predicate == null)
{
throw new ArgumentNullException(nameof(predicate));
}
return s_impl.Count(source, predicate);
}
#endregion
#region + ElementAt +
/// <summary>
/// Returns the element at a specified index in a sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Observable sequence to return the element from.</param>
/// <param name="index">The zero-based index of the element to retrieve.</param>
/// <returns>An observable sequence that produces the element at the specified position in the source sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.</exception>View on GitHub (pinned to 94b5d5ab91)