dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source')
Error message
Value cannot be null. (Parameter 'source')
What it means
ArgumentNullException thrown by Synchronization.SubscribeOn<TSource>(IObservable<TSource>, IScheduler) when the source sequence is null. SubscribeOn wraps the source in a SubscribeOnObservable so the Subscribe call itself runs on the given scheduler; the source must exist for that wrapper to delegate to.
Solutions
- Ensure the IObservable<TSource> passed to SubscribeOn is non-null; replace null-returning producers with Observable.Empty<TSource>() or Observable.Never<TSource>().
- Null-check the source before calling SubscribeOn and handle the null case (log, throw a domain error, or use a fallback sequence).
- Fix the upstream factory or DI registration so the observable is always produced instead of returning null.
- Guard at the call site so a null source fails fast with your own descriptive exception if that is the intended contract.
Example fix
// before IObservable<int> source = _repository.GetData(); // may return null var scheduled = source.SubscribeOn(Scheduler.ThreadPool); // after IObservable<int> source = _repository.GetData() ?? Observable.Empty<int>(); var scheduled = source.SubscribeOn(Scheduler.ThreadPool);
Defensive patterns
Strategy: validation
Validate before calling
if (source == null) throw new InvalidOperationException("Source observable must not be null before SubscribeOn");
var scheduled = source.SubscribeOn(Scheduler.ThreadPool); Type guard
bool IsUsableSource<TSource>(IObservable<TSource> source) => source is not null;
Try / catch
try
{
var scheduled = source.SubscribeOn(Scheduler.ThreadPool);
}
catch (ArgumentNullException ex) when (ex.ParamName == "source")
{
scheduled = Observable.Empty<TSource>().SubscribeOn(Scheduler.ThreadPool);
} Prevention
- Return Observable.Empty or Observable.Never from producers instead of null.
- Null-check observables returned from services before composing pipelines.
- Ensure DI registrations for observable dependencies exist before pipelines are built.
- Prefer Observable.Defer for lazily-created sources so construction errors surface at subscription time.
When it happens
Trigger: Calling source.SubscribeOn(scheduler) where the source expression evaluates to null — commonly a nullable field or property holding the observable, or a method that returned null instead of an empty or never sequence.
Common situations: Chaining off a repository or service method whose observable result is null on error paths; DI-resolved observables that failed to bind; legacy code returning null instead of Observable.Empty or Observable.Never.
Related errors
- Value cannot be null. (Parameter 'action')
- Value cannot be null. (Parameter 'scheduler')
- scheduler (Value cannot be null)
- action (Value cannot be null)
- scheduler (Value cannot be null)
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/89722758df07d9ea.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.cs:35
#region SubscribeOn
/// <summary>
/// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="scheduler">Scheduler to perform subscription and unsubscription actions on.</param>
/// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is <c>null</c>.</exception>
/// <remarks>
/// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified scheduler.
/// In order to invoke observer callbacks on the specified scheduler, e.g. to offload callback processing to a dedicated thread, use <see cref="Synchronization.ObserveOn{TSource}(IObservable{TSource}, IScheduler)"/>.
/// </remarks>
public static IObservable<TSource> SubscribeOn<TSource>(IObservable<TSource> source, IScheduler scheduler)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (scheduler == null)
{
throw new ArgumentNullException(nameof(scheduler));
}
return new SubscribeOnObservable<TSource>(source, scheduler);
}
private sealed class SubscribeOnObservable<TSource> : ObservableBase<TSource>
{
private sealed class Subscription : IDisposable
{
private SerialDisposableValue _cancel;
public Subscription(IObservable<TSource> source, IScheduler scheduler, IObserver<TSource> observer)
{View on GitHub (pinned to 94b5d5ab91)