dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'context')
Error message
Value cannot be null. (Parameter 'context')
What it means
NotifyOn<T>(IObserver<T>, SynchronizationContext) throws ArgumentNullException when the context parameter is null. The SynchronizationContext is used to build a SynchronizationContextScheduler that marshals callbacks (commonly to the UI thread), so it must be provided.
Solutions
- Capture the context on the UI thread first: var ctx = SynchronizationContext.Current; then pass it
- Use the IScheduler overload with an appropriate scheduler (e.g. DispatcherScheduler.Current for WPF) when no SynchronizationContext exists
- Post subscription setup to the UI thread so SynchronizationContext.Current is populated before NotifyOn is called
- Fallback: observer.NotifyOn(Scheduler.Default) if UI marshaling is not required
Example fix
// before var notified = observer.NotifyOn(SynchronizationContext.Current); // null on background thread // after // on the UI thread: _uiContext = SynchronizationContext.Current; // ... var notified = observer.NotifyOn(_uiContext ?? new SynchronizationContextScheduler(SynchronizationContext.Current ?? new SynchronizationContext()));
Defensive patterns
Strategy: validation
Validate before calling
var ctx = SynchronizationContext.Current ?? throw new InvalidOperationException("No SynchronizationContext; call from the UI thread.");
var notified = observer.NotifyOn(ctx); Type guard
static bool HasSyncContext(SynchronizationContext? c) => c is not null;
Try / catch
try { var notified = observer.NotifyOn(context); }
catch (ArgumentNullException ex) when (ex.ParamName == "context")
{
var notified = observer.NotifyOn(Scheduler.Default); // fallback, no UI marshaling
} Prevention
- Capture SynchronizationContext.Current on the UI thread and store it
- Never assume SynchronizationContext.Current is non-null on thread-pool threads
- Use DispatcherScheduler (WPF) or Control.BeginInvoke (WinForms) alternatives when no context exists
- Capture the context before starting background work
When it happens
Trigger: Calling observer.NotifyOn(null) — e.g. SynchronizationContext.Current is null (no UI thread context captured), or a context field never assigned.
Common situations: Calling SynchronizationContext.Current from a background/thread-pool thread where it is null; capturing the context too late (after the UI thread's message loop setup); unit tests without a synchronization context installed.
Related errors
- Value cannot be null. (Parameter 'action')
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'scheduler')
- Value cannot be null. (Parameter 'context')
- predicate
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/184bfaaa53c97c17.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Observer.Extensions.cs:327
/// <summary>
/// Schedules the invocation of observer methods on the given synchronization context.
/// </summary>
/// <typeparam name="T">The type of the elements received by the source observer.</typeparam>
/// <param name="observer">The observer to schedule messages for.</param>
/// <param name="context">Synchronization context to schedule observer messages on.</param>
/// <returns>Observer whose messages are scheduled on the given synchronization context.</returns>
/// <exception cref="ArgumentNullException"><paramref name="observer"/> or <paramref name="context"/> is null.</exception>
public static IObserver<T> NotifyOn<T>(this IObserver<T> observer, SynchronizationContext context)
{
if (observer == null)
{
throw new ArgumentNullException(nameof(observer));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
return new ObserveOnObserver<T>(new SynchronizationContextScheduler(context), observer);
}
/// <summary>
/// Converts an observer to a progress object.
/// </summary>
/// <typeparam name="T">The type of the progress objects received by the source observer.</typeparam>
/// <param name="observer">The observer to convert.</param>
/// <returns>Progress object whose Report messages correspond to the observer's OnNext messages.</returns>
/// <exception cref="ArgumentNullException"><paramref name="observer"/> is null.</exception>
public static IProgress<T> ToProgress<T>(this IObserver<T> observer)
{
if (observer == null)
{
throw new ArgumentNullException(nameof(observer));
}View on GitHub (pinned to 94b5d5ab91)