dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'scheduler')

Error message

Value cannot be null. (Parameter 'scheduler')

What it means

Replay(source, scheduler) throws ArgumentNullException('scheduler') when the scheduler argument is null. A scheduler is required for this overload because the replay subject (SequentialReplayAsyncSubject) uses it for time-based behavior; the library does not default to a standard scheduler implicitly here.

Solutions

  1. Pass an explicit scheduler, e.g. use the library's default/timeout scheduler singleton or your configured IAsyncScheduler.
  2. If you don't need custom scheduling, call the parameterless source.Replay() overload instead.
  3. Fix DI registration so an IAsyncScheduler is available at the call site.

Example fix

// before
IAsyncScheduler sched = null;
var replay = source.Replay(sched); // throws
// after
var replay = source.Replay(new DefaultAsyncScheduler()); // or source.Replay()
Defensive patterns

Strategy: validation

Validate before calling

if (scheduler == null)
    scheduler = new DefaultAsyncScheduler(); // or your configured IAsyncScheduler
var replay = source.Replay(scheduler);

Type guard

static bool HasScheduler(IAsyncScheduler? scheduler) => scheduler is not null;

Try / catch

try
{
    var replay = source.Replay(scheduler);
}
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler")
{
    var replay = source.Replay(); // fall back to parameterless overload
}

Prevention

When it happens

Trigger: Calling source.Replay(scheduler) with scheduler == null, e.g. an optional scheduler field that defaulted to null, or a DI container that failed to resolve the scheduler.

Common situations: DI misconfiguration where IAsyncScheduler isn't registered; passing a TaskPool/Default scheduler variable that was never initialized; test setups that forgot to supply a test scheduler.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/d18083feb4dd7237. Report an issue: GitHub.

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Replay.cs:28

{
    // REVIEW: Expose Replay using ConcurrentAsyncAsyncSubject<T> underneath.

    public partial class AsyncObservable
    {
        public static IConnectableAsyncObservable<TSource> Replay<TSource>(this IAsyncObservable<TSource> source)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

            return Multicast(source, new SequentialReplayAsyncSubject<TSource>());
        }

        public static IConnectableAsyncObservable<TSource> Replay<TSource>(this IAsyncObservable<TSource> source, IAsyncScheduler scheduler)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (scheduler == null)
                throw new ArgumentNullException(nameof(scheduler));

            return Multicast(source, new SequentialReplayAsyncSubject<TSource>(scheduler));
        }

        public static IConnectableAsyncObservable<TSource> Replay<TSource>(this IAsyncObservable<TSource> source, int bufferSize)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (bufferSize < 0)
                throw new ArgumentOutOfRangeException(nameof(bufferSize));

            return Multicast(source, new SequentialReplayAsyncSubject<TSource>(bufferSize));
        }

        public static IConnectableAsyncObservable<TSource> Replay<TSource>(this IAsyncObservable<TSource> source, int bufferSize, IAsyncScheduler scheduler)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

View on GitHub (pinned to 94b5d5ab91)