dotnet/reactive · error · ArgumentNullException

predicate

Error message

predicate

What it means

The synchronous-predicate SkipWhile extension validates its predicate and throws ArgumentNullException with paramName "predicate" when the Func<TSource, bool> is null. A null predicate cannot decide whether elements should be skipped.

Solutions

  1. Pass a non-null lambda or method group as the predicate.
  2. Fix the code path that yields a null predicate delegate.
  3. Coalesce to a default predicate if a null is acceptable in the domain.

Example fix

// before
Func<int, bool> pred = GetPredicate(); // may be null
var res = src.SkipWhile(pred);
// after
var res = src.SkipWhile(pred ?? (_ => true));
Defensive patterns

Strategy: validation

Validate before calling

if (predicate is null) throw new ArgumentException("predicate required", nameof(predicate));
var res = source.SkipWhile(predicate);

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling source.SkipWhile(predicate) with a null delegate, typically a predicate stored in a variable/field that was never assigned or returned null from a factory.

Common situations: Predicates passed in from configuration or caller arguments; test setups where the lambda variable is conditionally assigned.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/SkipWhile.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> SkipWhile<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.SkipWhile(observer, predicate)));
        }

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

View on GitHub (pinned to 94b5d5ab91)