dotnet/reactive · error · ArgumentNullException

Argument cannot be null (Parameter name: observer)

Error message

Argument cannot be null (Parameter name: observer)

What it means

AsyncObserver.FirstOrDefault<TSource>(IAsyncObserver<TSource>) (FirstOrDefault.cs:55) throws ArgumentNullException when the observer is null. This observer-level operator wraps the observer so the first element is echoed and then completes immediately; without an observer there is nothing to forward to, so the library fails fast at construction.

Solutions

  1. Forward the actual observer argument you received in the subscription delegate: static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.FirstOrDefault(observer)).
  2. If you must hold the observer in a field, initialize it before composing the operator.
  3. Add ThrowIfNull on the observer at the top of your custom operator for a clearer failure.

Example fix

// before
IAsyncObserver<int> _inner; // not yet assigned
var op = AsyncObserver.FirstOrDefault(_inner);

// after
return Create<int>(static (source, observer) =>
    source.SubscribeSafeAsync(AsyncObserver.FirstOrDefault(observer)));
Defensive patterns

Strategy: validation

Validate before calling

if (observer is null) throw new ArgumentNullException(nameof(observer));
var op = AsyncObserver.FirstOrDefault(observer);

Type guard

static bool HasObserver<T>(IAsyncObserver<T>? o) => o is not null;

Try / catch

try { var op = AsyncObserver.FirstOrDefault(observer); }
catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* fix observer wiring */ }

Prevention

When it happens

Trigger: Calling AsyncObserver.FirstOrDefault(null) directly, or from custom operator code where the IAsyncObserver passed into your Subscribe lambda was not forwarded (e.g. captured field still null).

Common situations: Hand-rolled operators that forget to pass the incoming observer down to AsyncObserver factories; test harnesses constructing observer chains out of order; wrapper classes lazily creating the inner observer after the operator call.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/FirstOrDefault.cs:55

        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (predicate == null)
                throw new ArgumentNullException(nameof(predicate));

            return Create(
                source,
                predicate,
                static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.FirstOrDefault(observer, predicate)));
        }
    }

    public partial class AsyncObserver
    {
        public static IAsyncObserver<TSource> FirstOrDefault<TSource>(IAsyncObserver<TSource> observer)
        {
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));

            return Create<TSource>(
                async x =>
                {
                    await observer.OnNextAsync(x).ConfigureAwait(false);
                    await observer.OnCompletedAsync().ConfigureAwait(false);
                },
                observer.OnErrorAsync,
                async () =>
                {
                    await observer.OnNextAsync(default).ConfigureAwait(false);
                    await observer.OnCompletedAsync().ConfigureAwait(false);
                }
            );
        }

        public static IAsyncObserver<TSource> FirstOrDefault<TSource>(IAsyncObserver<TSource> observer, Func<TSource, bool> predicate)
        {

View on GitHub (pinned to 94b5d5ab91)