dotnet/reactive · error · ArgumentNullException

ArgumentNullException

Error message

ArgumentNullException

What it means

AsyncObservableImpl's constructor validates its source observable and throws ArgumentNullException when source is null. Every IAsyncObservable operator implementation must be rooted in a non-null source; a null source would make SubscribeAsyncCore impossible to dispatch. The guard is fail-fast at construction time.

Solutions

  1. Ensure the source IAsyncObservable is non-null before passing it (e.g. source ?? AsyncObservable.Empty<T>())
  2. Check why the upstream factory/resolution returned null and fix the root cause
  3. Add an explicit null check with a clear message at the point where source is produced

Example fix

// before
var result = AsyncObservable.Select(GetSource(), x => x * 2); // GetSource() returned null
// after
var src = GetSource() ?? AsyncObservable.Empty<int>();
var result = AsyncObservable.Select(src, x => x * 2);
Defensive patterns

Strategy: validation

Validate before calling

if (source == null) throw new InvalidOperationException("source observable must be provided");

Type guard

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

Try / catch

try { var obs = AsyncObservable.Create(source, subscribe); } catch (ArgumentNullException ex) { /* ex.ParamName == "source" */ }

Prevention

When it happens

Trigger: Calling the internal AsyncObservableImpl<TSource, TResult>(null, subscribeAsync) constructor — typically reached via Create/From-style APIs when the upstream observable passed to them is null.

Common situations: Chaining operators on an observable variable that was never assigned (e.g. a conditional factory returned null); passing a method result as source without a null check; deserialized or resolved sources that came back null.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/AsyncObservable.cs:21

// See the LICENSE file in the project root for more information. 

using System.Reactive.Disposables;
using System.Threading.Tasks;

namespace System.Reactive.Linq
{
    public static partial class AsyncObservable
    {
        internal static class CreateAsyncObservable<TResult>
        {
            private sealed class AsyncObservableImpl<TSource> : AsyncObservableBase<TResult>
            {
                private readonly IAsyncObservable<TSource> _source;
                private readonly Func<IAsyncObservable<TSource>, IAsyncObserver<TResult>, ValueTask<IAsyncDisposable>> _subscribeAsync;

                public AsyncObservableImpl(IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, IAsyncObserver<TResult>, ValueTask<IAsyncDisposable>> subscribeAsync)
                {
                    _source = source ?? throw new ArgumentNullException(nameof(source));
                    _subscribeAsync = subscribeAsync ?? throw new ArgumentNullException(nameof(subscribeAsync));
                }

                protected override ValueTask<IAsyncDisposable> SubscribeAsyncCore(IAsyncObserver<TResult> observer)
                {
                    if (observer == null)
                        throw new ArgumentNullException(nameof(observer));

                    return _subscribeAsync(_source, observer);
                }
            }

            private sealed class AsyncObservableImpl<TSource, TState> : AsyncObservableBase<TResult>
            {
                private readonly TState _state;
                private readonly IAsyncObservable<TSource> _source;
                private readonly Func<IAsyncObservable<TSource>, TState, IAsyncObserver<TResult>, ValueTask<IAsyncDisposable>> _subscribeAsync;

View on GitHub (pinned to 94b5d5ab91)