dotnet/reactive · error · ArgumentNullException

condition

Error message

condition

What it means

AsyncObservable.If (Func<bool> overload) throws ArgumentNullException when the condition delegate is null. The condition decides at subscription time whether to run thenSource or elseSource; a null condition makes the operator's decision impossible, so it fails fast. Three sibling overloads (sync condition, async Func<ValueTask<bool>> condition, scheduler variants) enforce the same guard.

Solutions

  1. Pass a non-null Func<bool>, e.g. `() => featureEnabled`.
  2. Check you are calling the intended overload — a null where a scheduler or source is expected can shift into the condition slot.
  3. If the condition is optional by design, default it to `() => true` or `() => false` before calling.

Example fix

// before
var obs = AsyncObservable.If(null, thenSource, elseSource);
// after
var obs = AsyncObservable.If(() => settings.Enabled, thenSource, elseSource);
Defensive patterns

Strategy: validation

Validate before calling

if (condition == null) throw new ArgumentNullException(nameof(condition));
// or default: condition ??= () => true;

Type guard

bool HasCondition(Func<bool> f) => f is not null;

Try / catch

try { var obs = AsyncObservable.If(condition, thenSource, elseSource); }
catch (ArgumentNullException ex) when (ex.ParamName == "condition") { /* substitute default predicate and retry */ }

Prevention

When it happens

Trigger: Calling AsyncObservable.If(null, thenSource, elseSource) or If(null, thenSource, scheduler); commonly from a boolean-returning delegate stored in a nullable field or built from parsed configuration.

Common situations: Rule engines where predicates come from config/DI and may be unset; refactors replacing Func<bool> with Func<ValueTask<bool>> leaving the old null; template code with placeholder nulls.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/If.cs:19

// 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.Reactive.Concurrency;
using System.Threading.Tasks;

namespace System.Reactive.Linq
{
    public partial class AsyncObservable
    {
        public static IAsyncObservable<TResult> If<TResult>(Func<bool> condition, IAsyncObservable<TResult> thenSource) => If(condition, thenSource, Empty<TResult>());

        public static IAsyncObservable<TResult> If<TResult>(Func<bool> condition, IAsyncObservable<TResult> thenSource, IAsyncScheduler scheduler) => If(condition, thenSource, Empty<TResult>(scheduler));

        public static IAsyncObservable<TResult> If<TResult>(Func<bool> condition, IAsyncObservable<TResult> thenSource, IAsyncObservable<TResult> elseSource)
        {
            if (condition == null)
                throw new ArgumentNullException(nameof(condition));
            if (thenSource == null)
                throw new ArgumentNullException(nameof(thenSource));
            if (elseSource == null)
                throw new ArgumentNullException(nameof(elseSource));

            return CreateAsyncObservable<TResult>.From(
                thenSource,
                (elseSource, condition),
                static (thenSource, state, observer) =>
                {
                    var b = default(bool);

                    try
                    {
                        b = state.condition();
                    }
                    catch (Exception ex)
                    {

View on GitHub (pinned to 94b5d5ab91)