dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'predicate')

Error message

Value cannot be null. (Parameter 'predicate')

What it means

Thrown by the Single(source, Func<TSource,bool>) overload when the predicate delegate is null. The library validates both source and predicate before creating the operator pipeline. Without the guard the null would only explode when the first element is evaluated, far from the actual bug.

Solutions

  1. Pass a valid non-null Func<TSource,bool> predicate
  2. If no filtering is intended, call the parameterless SingleAsync(source) overload instead
  3. Verify any variable holding the predicate is assigned before the call

Example fix

// before
Func<int, bool> pred = GetPredicate(); // may be null
var result = await source.SingleAsync(pred);
// after
var result = await source.SingleAsync(x => x > 0);
Defensive patterns

Strategy: validation

Validate before calling

if (predicate is null) throw new InvalidOperationException("predicate must not be null");

Type guard

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

Try / catch

try { var v = await source.SingleAsync(pred); }
catch (ArgumentNullException ex) when (ex.ParamName == "predicate") { /* use default predicate */ }

Prevention

When it happens

Trigger: Calling SingleAsync(source, predicate) with a null predicate delegate, e.g. a lambda stored in a nullable field that was never initialized.

Common situations: Predicates built dynamically or read from configuration; refactoring that removed a lambda but left the call; passing a method group on a null object.

Related errors


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

Appendix: source

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

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

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

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

        public static IAsyncObservable<TSource> Single<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 CreateAsyncObservable<TSource>.From(
                source,
                predicate,
                static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.Single(observer, predicate)));
        }

        public static IAsyncObservable<TSource> Single<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 CreateAsyncObservable<TSource>.From(
                source,
                predicate,
                static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.Single(observer, predicate)));

View on GitHub (pinned to 94b5d5ab91)