dotnet/reactive · error · ArgumentNullException

throw new ArgumentNullException(nameof(predicate));

Error message

throw new ArgumentNullException(nameof(predicate));

What it means

The async TakeWhile(source, predicate) overload throws ArgumentNullException because the predicate argument was null. The Func<TSource, ValueTask<bool>> predicate drives per-element async filtering; the library validates it eagerly and throws with the parameter name 'predicate'. Both this and the source check sit at the top of the operator, so the failure is immediate and unambiguous.

Solutions

  1. Pass a non-null async predicate, e.g. async x => await CheckAsync(x).
  2. If the predicate is optional/dynamic, default to a constant-true async predicate: async _ => true.
  3. Check which overload you intended — a null sync Func passed where the ValueTask overload is selected still throws here.

Example fix

// before
Func<int, ValueTask<bool>> pred = BuildAsyncPredicate(rules); // null on failure
var taken = source.TakeWhile(pred);
// after
var taken = source.TakeWhile(pred ?? async _ => true);
Defensive patterns

Strategy: validation

Validate before calling

if (predicate == null) predicate = static async _ => true;

Type guard

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

Try / catch

try { var taken = source.TakeWhile(asyncPredicate); } catch (ArgumentNullException ex) when (ex.ParamName == "predicate") { var taken = source; /* no filtering */ }

Prevention

When it happens

Trigger: Calling AsyncObservable.TakeWhile(source, (Func<TSource, ValueTask<bool>>)null).

Common situations: An async predicate factory (e.g. building a ValueTask-returning lambda from rules) returned null; wrong overload resolution made the compiler pick the async overload while the caller supplied a null sync delegate variable; dynamic rule compilation failed silently upstream.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/TakeWhile.cs:29

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

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

        public static IAsyncObservable<TSource> TakeWhile<TSource>(this IAsyncObservable<TSource> source, Func<TSource, int, 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.TakeWhile(observer, predicate)));

View on GitHub (pinned to 94b5d5ab91)