dotnet/reactive · error · ArgumentNullException

elseSource

Error message

elseSource

What it means

AsyncObservable.If throws ArgumentNullException when elseSource is null. The elseSource runs when the condition evaluates false and must be a concrete observable; the guard ensures both branches exist at construction time. Thrown synchronously from the operator factory, so it points directly at the faulty call.

Solutions

  1. Supply a non-null elseSource observable.
  2. Use the scheduler overload If(condition, thenSource, scheduler) if you want an implicit Empty else branch.
  3. Substitute `elseSource ?? AsyncObservable.Empty<TResult>()` when the else branch is genuinely optional.

Example fix

// before
var obs = AsyncObservable.If(cond, thenSource, null);
// after
var obs = AsyncObservable.If(cond, thenSource, AsyncObservable.Empty<Result>());
Defensive patterns

Strategy: validation

Validate before calling

if (elseSource == null) throw new ArgumentNullException(nameof(elseSource));
// or coerce: elseSource ??= AsyncObservable.Empty<TResult>();

Type guard

bool HasElseSource<T>(IAsyncObservable<T> o) => o is not null;

Try / catch

try { var obs = AsyncObservable.If(condition, thenSource, elseSource); }
catch (ArgumentNullException ex) when (ex.ParamName == "elseSource") { /* fall back to Empty and log */ }

Prevention

When it happens

Trigger: Calling AsyncObservable.If(condition, thenSource, null) — often from conditional assembly where the else branch is optional, or a two-argument helper mistakenly calling the three-argument overload with a trailing null.

Common situations: Optional fallback semantics implemented as null instead of Empty; config-driven pipelines missing an else source; overload confusion between the scheduler overload (which fills else with Empty) and the two-source overload.

Related errors


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

Appendix: source

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

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)
                    {
                        return Throw<TResult>(ex).SubscribeAsync(observer);
                    }

                    return (b ? thenSource : state.elseSource).SubscribeSafeAsync(observer);

View on GitHub (pinned to 94b5d5ab91)