dotnet/reactive · error · ArgumentNullException

predicate

Error message

predicate

What it means

The TakeWhile(source, predicate) operator throws ArgumentNullException because the predicate delegate argument was null. The predicate is invoked for every emitted element to decide whether to keep taking; the library rejects a null predicate at pipeline-construction time with the parameter name 'predicate' in the message. A valid source does not prevent this throw.

Solutions

  1. Pass a concrete predicate, e.g. x => x > 0, or a named method group.
  2. If the predicate is built dynamically, fall back to a always-true predicate (x => true) when construction fails.
  3. Validate the delegate before composing the pipeline if it comes from external configuration.

Example fix

// before
Func<int, bool> pred = BuildPredicate(cfg); // may return null
var taken = source.TakeWhile(pred);
// after
var taken = source.TakeWhile(pred ?? (_ => true));
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling AsyncObservable.TakeWhile(source, null) where the Func<TSource, bool> argument is null.

Common situations: Building the predicate dynamically (e.g. from a filter expression) and the builder returned null; a config-driven filter string that failed to compile to a delegate; passing a method group that was removed/renamed during refactoring and now resolves via a null variable.

Related errors


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

Appendix: source

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

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information. 

using System.Threading.Tasks;

namespace System.Reactive.Linq
{
    public partial class AsyncObservable
    {
        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)));

View on GitHub (pinned to 94b5d5ab91)