dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'functionAsync')
Error message
Value cannot be null. (Parameter 'functionAsync')
What it means
Observable.StartAsync<TResult>(Func<Task<TResult>> functionAsync) throws ArgumentNullException when the async factory delegate is null. The delegate is the core of the operation — it produces the Task whose result the observable emits — so the library fails fast rather than producing an observable that errors only on subscribe.
Solutions
- Ensure the Func<Task<TResult>> delegate is assigned before calling StartAsync
- If the delegate is looked up, validate the lookup result and throw a clearer error
- Prefer passing the async method group directly (e.g. StartAsync(DoWorkAsync)) instead of a variable
Example fix
// before
Func<Task<int>> f = registry.GetHandler(name); // may be null
Observable.StartAsync(f);
// after
Func<Task<int>> f = registry.GetHandler(name) ?? throw new InvalidOperationException($"no handler for {name}");
Observable.StartAsync(f); Defensive patterns
Strategy: validation
Validate before calling
if (functionAsync == null) throw new ArgumentNullException(nameof(functionAsync)); Observable.StartAsync(functionAsync);
Type guard
bool IsValidAsync(Func<Task<TResult>> f) => f is not null;
Try / catch
try { Observable.StartAsync(functionAsync); }
catch (ArgumentNullException ex) when (ex.ParamName == "functionAsync") { log.LogError("StartAsync requires a non-null async delegate"); throw; } Prevention
- Pass async method groups directly instead of stored nullable delegates
- Fail fast where the delegate is resolved, not inside the Rx call
- Avoid conditionally assigned Func<Task<T>> variables
When it happens
Trigger: Calling Observable.StartAsync with a null Func<Task<TResult>>, e.g. an unassigned async lambda variable or a null returned from a strategy/registry lookup of async work.
Common situations: Conditional assignment of an async delegate, storing Func<Task<T>> in a nullable field populated asynchronously, or reflection-based delegate construction that silently failed.
Related errors
- Value cannot be null. (Parameter 'end')
- end
- begin
- Value cannot be null. (Parameter 'options')
- Value cannot be null. (Parameter 'resourceFactoryAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/69ae2a40294f4407.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Async.cs:1043
/// <summary>
/// Invokes the asynchronous function, surfacing the result through an observable sequence.
/// </summary>
/// <typeparam name="TResult">The type of the result returned by the asynchronous function.</typeparam>
/// <param name="functionAsync">Asynchronous function to run.</param>
/// <returns>An observable sequence exposing the function's result value, or an exception.</returns>
/// <exception cref="ArgumentNullException"><paramref name="functionAsync"/> is null.</exception>
/// <remarks>
/// <list type="bullet">
/// <item><description>The function is started immediately, not during the subscription of the resulting sequence.</description></item>
/// <item><description>Multiple subscriptions to the resulting sequence can observe the function's result.</description></item>
/// </list>
/// </remarks>
public static IObservable<TResult> StartAsync<TResult>(Func<Task<TResult>> functionAsync)
{
if (functionAsync == null)
{
throw new ArgumentNullException(nameof(functionAsync));
}
return s_impl.StartAsync(functionAsync);
}
/// <summary>
/// Invokes the asynchronous function, surfacing the result through an observable sequence.
/// </summary>
/// <typeparam name="TResult">The type of the result returned by the asynchronous function.</typeparam>
/// <param name="functionAsync">Asynchronous function to run.</param>
/// <param name="scheduler">Scheduler on which to notify observers.</param>
/// <returns>An observable sequence exposing the function's result value, or an exception.</returns>
/// <exception cref="ArgumentNullException"><paramref name="functionAsync"/> is null or <paramref name="scheduler"/> is null.</exception>
/// <remarks>
/// <list type="bullet">
/// <item><description>The function is started immediately, not during the subscription of the resulting sequence.</description></item>
/// <item><description>Multiple subscriptions to the resulting sequence can observe the function's result.</description></item>
/// </list>View on GitHub (pinned to 94b5d5ab91)