dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source')
Error message
Value cannot be null. (Parameter 'source')
What it means
ControlObservable.SubscribeOn throws ArgumentNullException when the source IObservable<TSource> is null. Extension methods on IObservable validate the receiver explicitly because a null 'this' does not throw on its own in C# extension-method calls. The scheduler-based subscribe redirection must not be built around a null sequence.
Solutions
- Ensure the source observable is non-null before calling SubscribeOn.
- If the source may be absent, guard with a null check or use Observable.Empty<TSource>() instead of null.
- Fix the upstream factory/property so it never returns a null IObservable.
Example fix
// before IObservable<Data> src = GetSource(); // returns null src.SubscribeOn(this.tabControl1).Subscribe(...); // after IObservable<Data> src = GetSource() ?? Observable.Empty<Data>(); src.SubscribeOn(this.tabControl1).Subscribe(...);
Defensive patterns
Strategy: validation
Validate before calling
if (source is null) throw new InvalidOperationException("source observable is null");
source.SubscribeOn(control); Type guard
bool HasSource<TSource>(IObservable<TSource> s) => s is not null;
Try / catch
try { source.SubscribeOn(control).Subscribe(obs); } catch (ArgumentNullException ex) when (ex.ParamName == "source") { Log("Source observable was null"); } Prevention
- Never let factories return null IObservable; return Observable.Empty or Throw
- Null-check the result of service/property lookups before Rx chaining
- Enable nullable reference types to catch null observables at compile time
When it happens
Trigger: Calling nullObservable.SubscribeOn(someControl) — typically when the observable came from a factory, service, or property that returned null.
Common situations: Chained Rx queries where an earlier operator or a lazy provider produced null instead of an empty/throwing sequence; dependency injection returning null for an observable service.
Related errors
- Value cannot be null. (Parameter 'control')
- Value cannot be null. (Parameter 'action')
- Value cannot be null. (Parameter 'source')
- nameof(onError)
- nameof(onCompleted)
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/359c910a13d54f9e.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive.Windows.Forms/System.Reactive.Linq/ControlObservable.cs:35
public static class ControlObservable
{
/// <summary>
/// Wraps the source sequence in order to run its subscription and unsubscription logic on the Windows Forms message loop associated with the specified control.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="control">Windows Forms control whose associated message loop is used to perform subscription and unsubscription actions on.</param>
/// <returns>The source sequence whose subscriptions and unsubscriptions happen on the Windows Forms message loop associated with the specified control.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="control"/> is null.</exception>
/// <remarks>
/// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified control.
/// In order to invoke observer callbacks on the specified control, e.g. to render results in a control, use <see cref="ObserveOn"/>.
/// </remarks>
public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, Control control)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (control == null)
{
throw new ArgumentNullException(nameof(control));
}
return Synchronization.SubscribeOn(source, new ControlScheduler(control));
}
/// <summary>
/// Wraps the source sequence in order to run its observer callbacks on the Windows Forms message loop associated with the specified control.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="control">Windows Forms control whose associated message loop is used to notify observers on.</param>
/// <returns>The source sequence whose observations happen on the Windows Forms message loop associated with the specified control.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="control"/> is null.</exception>View on GitHub (pinned to 94b5d5ab91)