dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'onNextAsync')
Error message
Value cannot be null. (Parameter 'onNextAsync')
What it means
UnsafeAsyncObserver wraps three delegates (onNextAsync, onErrorAsync, onCompletedAsync) that its On*Async methods invoke directly; null delegates would crash mid-stream. The constructor therefore throws ArgumentNullException for the first, onNextAsync, when null.
Solutions
- Pass a non-null Func<T, ValueTask> as onNextAsync (use _ => default(ValueTask) for a no-op).
- Check ordering of arguments — onNext comes first, before onErrorAsync and onCompletedAsync.
- Fix the producer/factory returning the null delegate.
Example fix
// before
var observer = new UnsafeAsyncObserver<int>(maybeNext, OnError, OnCompleted);
// after
var observer = new UnsafeAsyncObserver<int>(
maybeNext ?? (x => default), OnError, OnCompleted); Defensive patterns
Strategy: validation
Validate before calling
if (onNextAsync is null) throw new ArgumentNullException(nameof(onNextAsync)); var observer = new UnsafeAsyncObserver<T>(onNextAsync, onErrorAsync, onCompletedAsync);
Type guard
static bool HasOnNext<T>(Func<T, ValueTask>? f) => f is not null;
Try / catch
try { var obs = new UnsafeAsyncObserver<int>(onNext, onError, onCompleted); }
catch (ArgumentNullException ex) when (ex.ParamName == "onNextAsync")
{ log.LogError("onNextAsync delegate was null"); } Prevention
- Use no-op lambdas (_ => default) instead of null for unused observer callbacks.
- Double-check argument order: onNextAsync comes first.
- Load delegate dependencies from DI with required bindings so they cannot be null.
When it happens
Trigger: Calling new UnsafeAsyncObserver<T>(null, onErrorAsync, onCompletedAsync) — e.g. building an observer programmatically where the next-handler is conditionally constructed or comes from a null-returning factory.
Common situations: Constructing observers from configuration/delegates loaded from DI where one binding is missing; generic helper methods forwarding possibly-null lambdas; typos passing arguments in the wrong order.
Related errors
- Value cannot be null. (Parameter 'observer')
- null (Parameter 'observer')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'observer')
- observer
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/76f9be21a2b6fb51.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Internal/UnsafeAsyncObserver.cs:17
// 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
{
public class UnsafeAsyncObserver<T> : IAsyncObserver<T>
{
private readonly Func<T, ValueTask> _onNextAsync;
private readonly Func<Exception, ValueTask> _onErrorAsync;
private readonly Func<ValueTask> _onCompletedAsync;
public UnsafeAsyncObserver(Func<T, ValueTask> onNextAsync, Func<Exception, ValueTask> onErrorAsync, Func<ValueTask> onCompletedAsync)
{
_onNextAsync = onNextAsync ?? throw new ArgumentNullException(nameof(onNextAsync));
_onErrorAsync = onErrorAsync ?? throw new ArgumentNullException(nameof(onErrorAsync));
_onCompletedAsync = onCompletedAsync ?? throw new ArgumentNullException(nameof(onCompletedAsync));
}
public ValueTask OnCompletedAsync() => _onCompletedAsync();
public ValueTask OnErrorAsync(Exception error) => _onErrorAsync(error ?? throw new ArgumentNullException(nameof(error)));
public ValueTask OnNextAsync(T value) => _onNextAsync(value);
}
}
View on GitHub (pinned to 94b5d5ab91)