dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'scheduler')
Error message
Value cannot be null. (Parameter 'scheduler')
What it means
ScheduledDisposable's constructor requires a non-null IScheduler on which the wrapped resource will be disposed; null is rejected with ArgumentNullException. The scheduler is stored in a get-only property and is essential for DisposeAsync/Dispose routing.
Solutions
- Pass an actual scheduler instance, e.g. Scheduler.Default or Scheduler.Immediate.
- Resolve/register IScheduler in your DI container before constructing the ScheduledDisposable.
- Fall back to Scheduler.Immediate when no scheduler is configured and immediate disposal is acceptable.
Example fix
// before var sd = new ScheduledDisposable(configuredScheduler, resource); // configuredScheduler is null // after var sd = new ScheduledDisposable(configuredScheduler ?? Scheduler.Default, resource);
Defensive patterns
Strategy: validation
Validate before calling
if (scheduler is null) scheduler = Scheduler.Default; var sd = new ScheduledDisposable(scheduler, resource);
Type guard
static bool HasScheduler(IScheduler s) => s is not null;
Try / catch
try { var sd = new ScheduledDisposable(scheduler, resource); }
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { /* use Scheduler.Default fallback */ } Prevention
- Register IScheduler in DI and verify resolution at startup.
- Default to Scheduler.Default/Immediate at composition edges instead of null.
- Enable nullable reference types to catch unassigned scheduler variables at compile time.
When it happens
Trigger: Calling new ScheduledDisposable(null, someDisposable) — passing null for the 'scheduler' parameter, e.g. when a scheduler variable or DI-resolved IScheduler is null.
Common situations: DI container that failed to register IScheduler, configuration where the scheduler is chosen conditionally and both branches yield null, or testing code with a stubbed scheduler left unassigned.
Related errors
- Value cannot be null. (Parameter 'scheduler')
- Value cannot be null. (Parameter 'scheduler')
- Value cannot be null. (Parameter 'disposable')
- Value cannot be null. (Parameter 'disposable')
- throw new ArgumentNullException(nameof(scheduler));
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2d9cacf0cd6d9b54.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Disposables/ScheduledDisposable.cs:24
namespace System.Reactive.Disposables
{
/// <summary>
/// Represents a disposable resource whose disposal invocation will be scheduled on the specified <seealso cref="IScheduler"/>.
/// </summary>
public sealed class ScheduledDisposable : ICancelable
{
private SingleAssignmentDisposableValue _disposable;
/// <summary>
/// Initializes a new instance of the <see cref="ScheduledDisposable"/> class that uses an <see cref="IScheduler"/> on which to dispose the disposable.
/// </summary>
/// <param name="scheduler">Scheduler where the disposable resource will be disposed on.</param>
/// <param name="disposable">Disposable resource to dispose on the given scheduler.</param>
/// <exception cref="ArgumentNullException"><paramref name="scheduler"/> or <paramref name="disposable"/> is null.</exception>
public ScheduledDisposable(IScheduler scheduler, IDisposable disposable)
{
Scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler));
_disposable.Disposable = disposable ?? throw new ArgumentNullException(nameof(disposable));
}
/// <summary>
/// Gets the scheduler where the disposable resource will be disposed on.
/// </summary>
public IScheduler Scheduler { get; }
/// <summary>
/// Gets the underlying disposable. After disposal, the result is undefined.
/// </summary>
public IDisposable Disposable => _disposable.Disposable ?? Disposables.Disposable.Empty;
/// <summary>
/// Gets a value that indicates whether the object is disposed.
/// </summary>
public bool IsDisposed => _disposable.IsDisposed;
View on GitHub (pinned to 94b5d5ab91)