dotnet/reactive · error · ArgumentNullException
Argument cannot be null (Parameter name: predicate)
Error message
Argument cannot be null (Parameter name: predicate)
What it means
AsyncObserver.First (the observer-level overload taking a sync predicate) throws ArgumentNullException when the predicate delegate is null. The AsyncRx operators validate all delegate arguments up front because a null predicate would only explode later, mid-stream, when the first element arrives. Failing fast at operator-construction time keeps the error at the call site where it can be fixed.
Solutions
- Pass a real predicate; for 'no filtering' semantics call the First overload without a predicate instead of passing null.
- If the predicate is computed, default it before the call: predicate ?? (_ => true) only when filtering is intentionally bypassed.
- Check the caller (FirstAsync) at First.cs and ensure the value forwarded is a non-null delegate; guard at your own boundary with ArgumentNullException.ThrowIfNull(predicate).
Example fix
// before Func<int, bool> pred = condition ? x => x > 0 : null; var obs = AsyncObserver.First(observer, pred); // after var obs = condition ? AsyncObserver.First(observer, (int x) => x > 0) : AsyncObserver.First(observer);
Defensive patterns
Strategy: validation
Validate before calling
if (predicate is null) throw new ArgumentNullException(nameof(predicate)); var obs = AsyncObserver.First(observer, predicate);
Type guard
static bool IsValid<T>(Func<T, bool>? p) => p is not null;
Try / catch
try { var obs = AsyncObserver.First(observer, predicate); }
catch (ArgumentNullException ex) when (ex.ParamName == "predicate") { /* supply default predicate or log */ } Prevention
- Never store delegates in nullable fields consumed by Rx operators
- Use the parameterless-predicate overload for unfiltered semantics
- Enable nullable reference types so NRT warnings flag null delegate paths
When it happens
Trigger: Calling AsyncObserver.First(observer, predicate) (Func<TSource, bool> overload) with a null predicate, typically via FirstAsync(source, (Func<TSource,bool>)null) or by passing a nullable delegate variable that was never assigned.
Common situations: Conditional predicate construction (build predicate only if a filter flag is set) that leaves the variable null; casting/reflective invocation passing null for the optional filter; refactoring where a lambda was moved out and the variable lost its initializer.
Related errors
- Argument cannot be null (Parameter name: predicate)
- predicate
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'error')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/ca0eab046361e7d8.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/First.cs:76
async x =>
{
await observer.OnNextAsync(x).ConfigureAwait(false);
await observer.OnCompletedAsync().ConfigureAwait(false);
},
observer.OnErrorAsync,
async () =>
{
await observer.OnErrorAsync(new InvalidOperationException("The sequence is empty.")).ConfigureAwait(false);
}
);
}
public static IAsyncObserver<TSource> First<TSource>(IAsyncObserver<TSource> observer, Func<TSource, bool> predicate)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (predicate == null)
throw new ArgumentNullException(nameof(predicate));
return Where(First(observer), predicate);
}
public static IAsyncObserver<TSource> First<TSource>(IAsyncObserver<TSource> observer, Func<TSource, ValueTask<bool>> predicate)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (predicate == null)
throw new ArgumentNullException(nameof(predicate));
return Where(First(observer), predicate);
}
}
}
View on GitHub (pinned to 94b5d5ab91)