dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'observer')

Error message

Value cannot be null. (Parameter 'observer')

What it means

This ArgumentNullException is thrown by AsyncObserver.SumInt32(IAsyncObserver<int>) when the downstream observer is null. This is a lower-level factory in System.Reactive.Async that builds the aggregation observer; it's normally called by the Sum operator but can be invoked directly in custom operator or observer-composition code. The parameter 'observer' names the null argument.

Solutions

  1. Pass a valid IAsyncObserver<int>, e.g. one built via CreateObserver or obtained from your subscription pipeline.
  2. In custom Subscribe implementations, validate the observer argument and throw ArgumentNullException early (matching this library's behavior).
  3. If a factory returns the observer, check it for null before composing SumInt32 around it.

Example fix

// before
var sumObserver = AsyncObserver.SumInt32(_downstream); // _downstream may be null

// after
if (_downstream == null)
    throw new InvalidOperationException("Downstream observer not attached");
var sumObserver = AsyncObserver.SumInt32(_downstream);
Defensive patterns

Strategy: try-catch

Validate before calling

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

Type guard

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

Try / catch

try { var obs = AsyncObserver.SumInt32(downstream); }
catch (ArgumentNullException ex) when (ex.ParamName == "observer")
{
    throw new InvalidOperationException("Observer pipeline not attached before SumInt32", ex);
}

Prevention

When it happens

Trigger: Calling AsyncObserver.SumInt32(null) directly, or implementing a custom Create/Subscribe path that forwards a null observer (e.g. a custom IAsyncObservable whose Subscribe receives and passes through a null observer).

Common situations: Hit by authors of custom async-reactive operators, adapters wrapping other observer frameworks, or test code constructing observers piecemeal where the downstream observer was never created or a mock returned null.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Sum.cs:14

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information. 

using System.Threading.Tasks;

namespace System.Reactive.Linq
{
    public partial class AsyncObserver
    {
        public static IAsyncObserver<int> SumInt32(IAsyncObserver<int> observer)
        {
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));

            var sum = 0;

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

View on GitHub (pinned to 94b5d5ab91)