dotnet/reactive · error · ArgumentNullException

ArgumentNullException(nameof(source))

Error message

ArgumentNullException(nameof(source))

What it means

The synchronous-predicate Where extension validates its inputs first. It throws ArgumentNullException with param name 'source' when the IAsyncObservable<TSource> being filtered is null. Null-checking before CreateAsyncObservable.From gives an immediate, accurately-named exception instead of a confusing failure at subscription.

Solutions

  1. Ensure the source observable is created before filtering (e.g. AsyncObservable.Range(0, 10)).
  2. Fix the producer that returned null instead of a non-null (possibly empty) observable.
  3. Guard the chain: if (source == null) throw new InvalidOperationException(...) or coalesce with a default source.

Example fix

// before
IAsyncObservable<int> source = null;
var filtered = source.Where(x => x > 2); // throws
// after
var source = AsyncObservable.Range(0, 10);
var filtered = source.Where(x => x > 2);
Defensive patterns

Strategy: validation

Validate before calling

if (source == null)
    throw new InvalidOperationException("source observable must not be null before Where");

Type guard

bool HasSource<T>(IAsyncObservable<T> source) => source is not null;

Try / catch

try
{
    var filtered = source.Where(x => x > 2);
}
catch (ArgumentNullException ex) when (ex.ParamName == "source")
{
    // substitute AsyncObservable.Empty<T>() or report the null-producing factory
}

Prevention

When it happens

Trigger: Chaining .Where(predicate) on an IAsyncObservable<TSource> variable/return value that is null — e.g. a factory method returned null or a field was never assigned.

Common situations: Source observables resolved from DI or a cache that returned null; method chains where an earlier operator returned null unexpectedly (custom operators); race where the field is assigned only after the query is composed.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Where.cs:14

// 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> Where<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.Where(observer, predicate)));
        }

        public static IAsyncObservable<TSource> Where<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,

View on GitHub (pinned to 94b5d5ab91)