dotnet/reactive · error · ArgumentNullException

Argument cannot be null (Parameter name: predicate)

Error message

Argument cannot be null (Parameter name: predicate)

What it means

FirstOrDefault<TSource>(source, Func<TSource,bool>) (FirstOrDefault.cs:28) throws ArgumentNullException when the predicate delegate is null. The overload requires a filter; passing null would break AsyncObserver.FirstOrDefault(observer, predicate) at first emission, so validation happens eagerly at composition time with the parameter named in the message.

Solutions

  1. Always pass a concrete predicate; for 'match everything' use x => true.
  2. Use the no-predicate overload FirstOrDefaultAsync(source) when no filtering is wanted.
  3. Coalesce: source.FirstOrDefaultAsync(predicate ?? (_ => true)) only when bypass is intentional.

Example fix

// before
Expression<Func<int,bool>> pred = hasFilter ? x => x > min : null;
var first = src.FirstOrDefaultAsync(pred?.Compile());

// after
var first = hasFilter ? src.FirstOrDefaultAsync(x => x > min) : src.FirstOrDefaultAsync();
Defensive patterns

Strategy: validation

Validate before calling

if (predicate is null) throw new ArgumentNullException(nameof(predicate));
var first = source.FirstOrDefaultAsync(predicate);

Type guard

static bool HasPredicate<T>(Func<T, bool>? p) => p is not null;

Try / catch

try { var first = src.FirstOrDefaultAsync(pred); }
catch (ArgumentNullException ex) when (ex.ParamName == "predicate") { /* use unfiltered overload */ }

Prevention

When it happens

Trigger: Calling FirstOrDefaultAsync(source, (Func<TSource,bool>)null) — e.g. a conditionally built filter delegate, a nullable Func field, or reflection-based invocation supplying null for the predicate slot.

Common situations: UI-driven filter construction where the user hasn't chosen a predicate yet; generic query-builder code that appends filters optionally but always calls the filtered overload; migrating from LINQ's Where-style APIs that sometimes tolerate null (they don't here either).

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/cce0c3edd66788ea. Report an issue: GitHub.

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/FirstOrDefault.cs:28

    {
        public static IAsyncObservable<TSource> FirstOrDefaultAsync<TSource>(this IAsyncObservable<TSource> source) => FirstOrDefault(source);
        public static IAsyncObservable<TSource> FirstOrDefaultAsync<TSource>(this IAsyncObservable<TSource> source, Func<TSource, bool> predicate) => FirstOrDefault(source, predicate);
        public static IAsyncObservable<TSource> FirstOrDefaultAsync<TSource>(this IAsyncObservable<TSource> source, Func<TSource, ValueTask<bool>> predicate) => FirstOrDefault(source, predicate);

        public static IAsyncObservable<TSource> FirstOrDefault<TSource>(this IAsyncObservable<TSource> source)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

            return Create(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.FirstOrDefault(observer)));
        }

        public static IAsyncObservable<TSource> FirstOrDefault<TSource>(this IAsyncObservable<TSource> source, Func<TSource, bool> predicate)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (predicate == null)
                throw new ArgumentNullException(nameof(predicate));

            return Create(
                source,
                predicate,
                static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.FirstOrDefault(observer, predicate)));
        }

        public static IAsyncObservable<TSource> FirstOrDefault<TSource>(this IAsyncObservable<TSource> source, Func<TSource, ValueTask<bool>> predicate)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (predicate == null)
                throw new ArgumentNullException(nameof(predicate));

            return Create(
                source,
                predicate,
                static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.FirstOrDefault(observer, predicate)));

View on GitHub (pinned to 94b5d5ab91)