dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'observer')

Error message

Value cannot be null. (Parameter 'observer')

What it means

Thrown by AsyncObserver.Aggregate<TSource>(observer, func) when the downstream IAsyncObserver is null. This is the observer-side pipeline construction API; the observer parameter receives the final aggregated value and must be non-null.

Solutions

  1. Pass a non-null IAsyncObserver<TSource> (e.g. from AsyncObserver.Create or the observer obtained in your operator).
  2. Guard your custom operator: if observer == null throw ArgumentNullException(nameof(observer)) before delegating.
  3. Construct the observer explicitly instead of relying on an uninitialized field.

Example fix

// before
AsyncObserver.Aggregate(null, (a, x) => a + x);
// after
AsyncObserver.Aggregate(AsyncObserver.WriteConsole<int>(), (a, x) => a + x);
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Try / catch

try { var obs = AsyncObserver.Aggregate(observer, func); } catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* construct a default observer */ }

Prevention

When it happens

Trigger: Building a custom subscription pipeline and passing a null observer into AsyncObserver.Aggregate(observer, func), e.g. an uninitialized observer field or a null result of an observer factory.

Common situations: Composing AsyncObserver pipelines manually in custom operators; passing through an observer parameter that the caller supplied as null; test scaffolding with incomplete observer setup.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Aggregate.cs:99

                throw new ArgumentNullException(nameof(source));
            if (resultSelector == null)
                throw new ArgumentNullException(nameof(resultSelector));
            if (func == null)
                throw new ArgumentNullException(nameof(func));

            return CreateAsyncObservable<TResult>.From(
                source,
                (seed, func, resultSelector),
                static (source, state, observer) => source.SubscribeSafeAsync(AsyncObserver.Aggregate(observer, state.seed, state.func, state.resultSelector)));
        }
    }

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

            var hasValue = false;
            var value = default(TSource);

            return Create<TSource>(
                async x =>
                {
                    if (hasValue)
                    {
                        try
                        {
                            value = func(value, x);
                        }
                        catch (Exception ex)
                        {
                            await observer.OnErrorAsync(ex).ConfigureAwait(false);

View on GitHub (pinned to 94b5d5ab91)