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

  1. Capture the context on the UI thread first: var ctx = SynchronizationContext.Current; then pass it
  2. Use the IScheduler overload with an appropriate scheduler (e.g. DispatcherScheduler.Current for WPF) when no SynchronizationContext exists
  3. Post subscription setup to the UI thread so SynchronizationContext.Current is populated before NotifyOn is called
  4. 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

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


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)