AvaloniaUI/Avalonia · error · ArgumentNullException

Value cannot be null. (Parameter 'onNext')

Error message

Value cannot be null. (Parameter 'onNext')

What it means

AnonymousObserver<T>(Action<T> onNext, Action<Exception> onError, Action onCompleted) stores three callbacks; onNext is required and throws ArgumentNullException(nameof(onNext)) when null via the inline `?? throw`. Without an OnNext handler the observer is meaningless, so null is rejected at construction.

Source

Thrown at src/Avalonia.Base/Reactive/AnonymousObserver.cs:31

    private readonly Action<T> _onNext;
    private readonly Action<Exception> _onError;
    private readonly Action _onCompleted;

    public AnonymousObserver(TaskCompletionSource<T> tcs)
    {
        if (tcs is null)
        {
            throw new ArgumentNullException(nameof(tcs));
        }

        _onNext = tcs.SetResult;
        _onError = tcs.SetException;
        _onCompleted = NoOpCompleted;
    }
    
    public AnonymousObserver(Action<T> onNext, Action<Exception> onError, Action onCompleted)
    {
        _onNext = onNext ?? throw new ArgumentNullException(nameof(onNext));
        _onError = onError ?? throw new ArgumentNullException(nameof(onError));
        _onCompleted = onCompleted ?? throw new ArgumentNullException(nameof(onCompleted));
    }

    public AnonymousObserver(Action<T> onNext)
        : this(onNext, ThrowsOnError, NoOpCompleted)
    {
    }

    public AnonymousObserver(Action<T> onNext, Action<Exception> onError)
        : this(onNext, onError, NoOpCompleted)
    {
    }

    public AnonymousObserver(Action<T> onNext, Action onCompleted)
        : this(onNext, ThrowsOnError, onCompleted)
    {
    }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Provide a non-null Action<T> as the onNext handler.
  2. Null-check delegate fields before constructing the observer, and skip subscription when null.
  3. Use a no-op (e.g. _ => { }) if you genuinely want to ignore items but still need the observer shape.

Example fix

// before
Action<T> onNext = null;
source.Subscribe(new AnonymousObserver<T>(onNext, onError, onDone)); // throws

// after
source.Subscribe(new AnonymousObserver<T>(x => Consume(x), onError, onDone));
Defensive patterns

Strategy: validation

Validate before calling

if (onNext is null) return;
source.Subscribe(new AnonymousObserver<T>(onNext, onError, onCompleted));

Type guard

bool HasOnNext<T>(Action<T>? a) => a is not null;

Prevention

When it happens

Trigger: Constructing AnonymousObserver<T> with a null first-argument Action<T>, or via the single/overload chain that forwards into this constructor.

Common situations: Building an observer from method-group or lambda variables where the onNext delegate was never assigned, or was set to a null delegate field.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/90cda21a2a3a3e4c. Report an issue: GitHub.