dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'predicate')

Error message

Value cannot be null. (Parameter 'predicate')

What it means

AsyncObserver.Last(observer, Func<TSource, ValueTask<bool>>) throws ArgumentNullException with the full message "Value cannot be null. (Parameter 'predicate')" when the async predicate delegate is null. Observer is checked first, then predicate.

Solutions

  1. Provide a valid async predicate: async x => await MatchAsync(x).
  2. Coalesce with a default: asyncPred ?? (_ => ValueTask.FromResult(true)).
  3. Use the non-predicate Last(observer) overload when no filtering is desired.

Example fix

// before
var o = AsyncObserver.Last(downstream, asyncPred); // null
// after
var o = AsyncObserver.Last(downstream, asyncPred ?? (_ => ValueTask.FromResult(true)));
Defensive patterns

Strategy: validation

Validate before calling

if (asyncPredicate is null) asyncPredicate = static _ => ValueTask.FromResult(true);
var o = AsyncObserver.Last(observer, asyncPredicate);

Type guard

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

Try / catch

try { var o = AsyncObserver.Last(observer, asyncPredicate); }
catch (ArgumentNullException ex) when (ex.ParamName == "predicate") { var o = AsyncObserver.Last(observer); }

Prevention

When it happens

Trigger: Calling AsyncObserver.Last(observer, (Func<TSource, ValueTask<bool>>)null); untyped null literals can be resolved to this overload and trip the guard.

Common situations: Passing null where an async filter is expected in config-driven query building; a cached delegate field never initialized before pipeline construction.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Last.cs:101

            );
        }

        public static IAsyncObserver<TSource> Last<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(Last(observer), predicate);
        }

        public static IAsyncObserver<TSource> Last<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(Last(observer), predicate);
        }
    }
}

View on GitHub (pinned to 94b5d5ab91)