dotnet/reactive · error · ArgumentNullException
functionAsync
Error message
functionAsync
What it means
StartAsync<TSource>(Func<ValueTask<TSource>>, IAsyncScheduler) throws ArgumentNullException when the functionAsync delegate is null. The operator immediately invokes the delegate to obtain the ValueTask and convert it to a Task, so null is rejected up front.
Solutions
- Pass a non-null Func<ValueTask<TSource>>
- Guard the call site if the delegate is optional
- Trace why the delegate source was null
Example fix
// before
var xs = StartAsync(maybeFetch); // maybeFetch is null
// after
if (maybeFetch != null) { var xs = StartAsync(maybeFetch); } Defensive patterns
Strategy: validation
Validate before calling
if (functionAsync == null) throw new ArgumentNullException(nameof(functionAsync));
Type guard
static bool IsValidFunction<TSource>(Func<ValueTask<TSource>> f) => f is not null;
Prevention
- Check delegate-producing factories/lookups for null returns
- Use pattern matching (is not null) before invoking operators
- Wrap optional delegates in guard clauses at call sites
When it happens
Trigger: Calling StartAsync with a null async function delegate, with either the one- or two-argument overload (the one-argument overload forwards to this one).
Common situations: Uninitialized Func fields, conditional async handlers that are null, DI or factory returning null for the delegate.
Related errors
- null (Parameter 'scheduler')
- null (Parameter 'values')
- action
- actionAsync
- Value cannot be null. (Parameter 'onErrorAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/918b7d64120fbc95.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/StartAsync.cs:19
// 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.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Threading;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> StartAsync<TSource>(Func<ValueTask<TSource>> functionAsync) => StartAsync(functionAsync, ImmediateAsyncScheduler.Instance);
public static IAsyncObservable<TSource> StartAsync<TSource>(Func<ValueTask<TSource>> functionAsync, IAsyncScheduler scheduler)
{
if (functionAsync == null)
throw new ArgumentNullException(nameof(functionAsync));
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
Task<TSource> task;
try
{
task = functionAsync().AsTask();
}
catch (Exception ex)
{
return Throw<TSource>(ex);
}
return task.ToAsyncObservable(scheduler);
}
public static IAsyncObservable<TSource> StartAsync<TSource>(Func<CancellationToken, ValueTask<TSource>> functionAsync) => StartAsync(functionAsync, ImmediateAsyncScheduler.Instance);View on GitHub (pinned to 94b5d5ab91)