dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'observer')

Error message

Value cannot be null. (Parameter 'observer')

What it means

AsyncObserver.LongCount<TSource>(IAsyncObserver<long>) at LongCount.cs:51 creates the counting observer stage and requires a non-null downstream observer to forward the final count and completion to. A null observer means there is no consumer, so ArgumentNullException is thrown.

Solutions

  1. Pass the observer you are forwarding to (typically the one received in your SubscribeAsync delegate).
  2. Check your custom operator wiring: the downstream observer must be resolved before constructing LongCount.
  3. If the downstream may be absent, delay observer construction until subscription time when the real observer is available.

Example fix

// before
return AsyncObserver.LongCount<T>(downstream); // downstream null
// after
if (downstream == null) throw new ArgumentNullException(nameof(downstream));
return AsyncObserver.LongCount<T>(downstream);
Defensive patterns

Strategy: validation

Validate before calling

if (observer is null) throw new ArgumentNullException(nameof(observer));
var counting = AsyncObserver.LongCount<T>(observer);

Type guard

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

Try / catch

try { var stage = AsyncObserver.LongCount<T>(observer); }
catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* fix observer wiring */ throw; }

Prevention

When it happens

Trigger: Calling AsyncObserver.LongCount<TSource>(null) when composing custom observer pipelines.

Common situations: Custom operator authors wiring observer chains where the downstream observer came from a nullable field or an earlier factory call that returned null.

Related errors


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

Appendix: source

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

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

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

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

            var count = 0L;

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

View on GitHub (pinned to 94b5d5ab91)