dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'onErrorAsync')
Error message
Value cannot be null. (Parameter 'onErrorAsync')
What it means
UsingAsync is the ValueTask-based variant of Using for asynchronous resource acquisition. It guards the async resource factory eagerly; a null Func<ValueTask<TResource>> cannot be awaited at subscription time, so ArgumentNullException(nameof(resourceFactory)) is thrown at composition (Using.cs:63).
Solutions
- Pass a non-null Func<ValueTask<TResource>>, e.g. async () => await ConnectAsync()
- Wrap sync creation as () => new ValueTask<TResource>(Create())
- Null-check async factory delegates resolved at runtime before composing
Example fix
// before Func<ValueTask<DbConnection>> factory = useAsync ? null : MakeFactory(); var op = AsyncObservable.UsingAsync(factory, conn => QueryAsync(conn)); // after var op = AsyncObservable.UsingAsync(async () => await ConnectAsync(), conn => QueryAsync(conn));
Defensive patterns
Strategy: validation
Validate before calling
if (resourceFactory is null) throw new ArgumentNullException(nameof(resourceFactory)); var op = AsyncObservable.UsingAsync(resourceFactory, observableFactory);
Type guard
static bool ValidUsingAsyncArgs<TResource,TResult>(Func<ValueTask<TResource>> rf, Func<TResource,ValueTask<IAsyncObservable<TResult>>> of) => rf != null && of != null;
Try / catch
try
{
var op = AsyncObservable.UsingAsync(resourceFactory, observableFactory);
}
catch (ArgumentNullException ex) when (ex.ParamName == "resourceFactory")
{
// fall back to sync creation: () => new ValueTask<TResource>(CreateSync())
} Prevention
- Wrap sync factories as () => new ValueTask<TResource>(Create()) when migrating to UsingAsync
- Assert async factory delegates are assigned during configuration validation
- Avoid ternaries that leave a null branch for factory delegates
When it happens
Trigger: Calling AsyncObservable.UsingAsync<TResult, TResource>(null, observableFactory) with TResource : IDisposable.
Common situations: Async factory supplied only when a connection string/config is present; migration from sync Using to UsingAsync leaving one argument null; factory retrieved from an optional service provider.
Related errors
- Value cannot be null. (Parameter 'onNextAsync')
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
- null (Parameter 'scheduler')
- null (Parameter 'values')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/3741a2592a617abd.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/AsyncObservableExtensions.cs:29
{
public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Func<T, ValueTask> onNextAsync)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onNextAsync == null)
throw new ArgumentNullException(nameof(onNextAsync));
return source.SubscribeAsync(new AsyncObserver<T>(onNextAsync, ex => new ValueTask(Task.FromException(ex)), () => default));
}
public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Func<T, ValueTask> onNextAsync, Func<Exception, ValueTask> onErrorAsync)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onNextAsync == null)
throw new ArgumentNullException(nameof(onNextAsync));
if (onErrorAsync == null)
throw new ArgumentNullException(nameof(onErrorAsync));
return source.SubscribeAsync(new AsyncObserver<T>(onNextAsync, onErrorAsync, () => default));
}
public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Func<T, ValueTask> onNextAsync, Func<ValueTask> onCompletedAsync)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onNextAsync == null)
throw new ArgumentNullException(nameof(onNextAsync));
if (onCompletedAsync == null)
throw new ArgumentNullException(nameof(onCompletedAsync));
return source.SubscribeAsync(new AsyncObserver<T>(onNextAsync, ex => new ValueTask(Task.FromException(ex)), onCompletedAsync));
}
public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Func<T, ValueTask> onNextAsync, Func<Exception, ValueTask> onErrorAsync, Func<ValueTask> onCompletedAsync)
{View on GitHub (pinned to 94b5d5ab91)