dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'action')
Error message
Value cannot be null. (Parameter 'action')
What it means
DispatcherScheduler.Schedule<TState>(state, action) throws ArgumentNullException when the action delegate is null. The action is what gets BeginInvoke'd on the Dispatcher; there is nothing meaningful to schedule without it.
Solutions
- Ensure a non-null Func<IScheduler, TState, IDisposable> is passed to Schedule.
- If the work may be absent, schedule a no-op: (scheduler, state) => Disposable.Empty.
- Check any wrapper around IScheduler so it propagates real delegates rather than null.
Example fix
// before
scheduler.Schedule(state, null);
// after
scheduler.Schedule(state, (sched, st) => { DoWork(st); return Disposable.Empty; }); Defensive patterns
Strategy: validation
Validate before calling
if (action == null) throw new InvalidOperationException("schedule action required"); Type guard
bool HasAction<TState>(Func<IScheduler, TState, IDisposable> a) => a is not null;
Try / catch
try { scheduler.Schedule(state, action); } catch (ArgumentNullException ex) when (ex.ParamName == "action") { /* fix delegate */ } Prevention
- Return Disposable.Empty no-op lambdas instead of null for empty work.
- Keep delegates in non-nullable fields/parameters.
- Wrap IScheduler usage in a helper that asserts non-null actions once.
When it happens
Trigger: Calling scheduler.Schedule(state, null) directly, or passing a null action into Schedule(TimeSpan)/Schedule(DateTimeOffset) overloads that forward to this method (they null-check the forwarded delegate).
Common situations: Building a scheduling pipeline where the work delegate is produced dynamically and can be null; IScheduler abstraction code passing through a null action from an upstream operator; tests verifying argument checking (Schedule_ArgumentChecking).
Related errors
- scheduler
- Value cannot be null. (Parameter 'dispatcher')
- Value cannot be null. (Parameter 'scheduler')
- Value cannot be null. (Parameter 'iterate')
- Value cannot be null. (Parameter 'resultSelector')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/7f68aadf438d152f.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive.Wpf/System.Reactive.Concurrency/DispatcherScheduler.cs:87
/// <summary>
/// Gets the priority at which work items will be dispatched.
/// </summary>
public System.Windows.Threading.DispatcherPriority Priority { get; }
/// <summary>
/// Schedules an action to be executed on the dispatcher.
/// </summary>
/// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
/// <param name="state">State passed to the action to be executed.</param>
/// <param name="action">Action to be executed.</param>
/// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
/// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
{
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
var d = new SingleAssignmentDisposable();
Dispatcher.BeginInvoke(
new Action(() =>
{
if (!d.IsDisposed)
{
d.Disposable = action(this, state);
}
}),
Priority
);
return d;
}
View on GitHub (pinned to 94b5d5ab91)