dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'observer')

Error message

Value cannot be null. (Parameter 'observer')

What it means

AsyncObserver.Count<TSource>(observer) throws ArgumentNullException because the downstream IAsyncObserver<int> is null. This low-level observer factory increments a counter and must deliver the final count to the given observer; with a null observer the result would be undeliverable, so it fails fast at construction.

Solutions

  1. Pass the observer supplied to your subscribe callback: (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Count<T>(observer)).
  2. Create a terminal observer via AsyncObserver.Create<int>(onNextAsync, ...) to collect the count.
  3. Prefer the high-level AsyncObservable.Count() extension, which wires observers correctly.

Example fix

// before
return Create<int, int>((source, observer) => source.SubscribeSafeAsync(AsyncObserver.Count<int>(null)));
// after
return Create<int, int>((source, observer) => source.SubscribeSafeAsync(AsyncObserver.Count<int>(observer)));
Defensive patterns

Strategy: try-catch

Validate before calling

if (observer is null) throw new ArgumentNullException(nameof(observer));

Type guard

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

Try / catch

try { var obs = AsyncObserver.Count<T>(observer); } catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* wire the real downstream observer */ }

Prevention

When it happens

Trigger: Calling AsyncObserver.Count<TSource>(null) inside custom operator composition, e.g. inside a Create delegate where the observer parameter was misnamed or shadowed by a null variable.

Common situations: Authoring custom AsyncRx.NET operators; miswiring in Create<TSource,int> callbacks; test harnesses constructing observers manually and passing null placeholders.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Count.cs:51

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

            return CreateAsyncObservable<int>.From(
                source,
                predicate,
                static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.Count(observer, predicate)));
        }
    }

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

            var count = 0;

            return Create<TSource>(
                async x =>
                {
                    try
                    {
                        checked
                        {
                            count++;
                        }
                    }
                    catch (Exception ex)
                    {
                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
                        return;
                    }

View on GitHub (pinned to 94b5d5ab91)