dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'predicate')

Error message

Value cannot be null. (Parameter 'predicate')

What it means

ArgumentNullException thrown by the LastOrDefault(source, Func<TSource,bool> predicate) overload when the predicate delegate is null. The library validates both parameters synchronously before building the operator pipeline, so the throw occurs at the call site, not during subscription.

Solutions

  1. Pass a non-null predicate delegate to LastOrDefault
  2. If filtering is optional, branch: omit the predicate overload entirely when the filter is null
  3. Provide an always-true predicate (e.g. _ => true) when you want no filtering
  4. Fix the caller that forwarded a null filter

Example fix

// before
var last = source.LastOrDefault(filter);
// after
var last = filter != null ? source.LastOrDefault(filter) : source.LastOrDefault();
Defensive patterns

Strategy: validation

Validate before calling

if (predicate is null) throw new ArgumentNullException(nameof(predicate));
// or skip filtering when null:
var result = filter != null ? source.LastOrDefault(filter) : source.LastOrDefault();

Type guard

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

Try / catch

try
{
    var last = await source.LastOrDefaultAsync(pred);
}
catch (ArgumentNullException ex) when (ex.ParamName == "predicate")
{
    // fall back to unfiltered query or default
}

Prevention

When it happens

Trigger: Calling LastOrDefault(source, null) — e.g. a predicate variable that was never assigned, or a conditional-filter API that passed its own null filter argument through.

Common situations: Passing an optional filter delegate that defaulted to null, reflection-based delegate construction that failed silently, or refactoring that removed the lambda but left the call.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/LastOrDefault.cs:30

        public static IAsyncObservable<TSource> LastOrDefaultAsync<TSource>(this IAsyncObservable<TSource> source, Func<TSource, bool> predicate) => LastOrDefault(source, predicate);
        public static IAsyncObservable<TSource> LastOrDefaultAsync<TSource>(this IAsyncObservable<TSource> source, Func<TSource, ValueTask<bool>> predicate) => LastOrDefault(source, predicate);

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

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

        public static IAsyncObservable<TSource> LastOrDefault<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.LastOrDefault(observer, predicate)));
        }

        public static IAsyncObservable<TSource> LastOrDefault<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.LastOrDefault(observer, predicate)));

View on GitHub (pinned to 94b5d5ab91)