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

  1. Pass a non-null Func<ValueTask<TSource>>
  2. Guard the call site if the delegate is optional
  3. 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

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


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)