dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'scheduler')
Error message
Value cannot be null. (Parameter 'scheduler')
What it means
The Take(source, duration, scheduler) overload of System.Reactive.Async requires a non-null IAsyncScheduler. The guard at Take.cs:66 throws ArgumentNullException because the scheduler parameter is null; the library refuses null dependencies up front rather than failing later during subscription.
Solutions
- Pass a concrete scheduler such as TaskPoolAsyncScheduler.Default or NewThreadAsyncScheduler.Default.
- If using DI, register IAsyncScheduler in the container and verify resolution returns non-null.
- If you intended immediate/synchronous behavior, use a scheduler implementation suited to that instead of null.
- If the duration is TimeSpan.Zero, use Empty<TSource>() directly so no scheduler is needed.
Example fix
// before: AsyncObservable.Take(source, TimeSpan.FromSeconds(1), null) // after: AsyncObservable.Take(source, TimeSpan.FromSeconds(1), TaskPoolAsyncScheduler.Default)
Defensive patterns
Strategy: validation
Validate before calling
if (source == null) throw new ArgumentNullException(nameof(source)); if (duration < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(duration)); if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); var result = AsyncObservable.Take(source, duration, scheduler);
Type guard
static bool IsValidTakeWindow<TSource>(IAsyncObservable<TSource> s, TimeSpan d, IAsyncScheduler sch) => s != null && d >= TimeSpan.Zero && sch != null;
Try / catch
try { var res = AsyncObservable.Take(source, duration, scheduler); } catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { scheduler = TaskPoolAsyncScheduler.Default; var res = AsyncObservable.Take(source, duration, scheduler); } Prevention
- Default scheduler fields to TaskPoolAsyncScheduler.Default at declaration.
- Register IAsyncScheduler in DI and verify at startup.
- Never pass null for scheduler; use the 2-arg overload when you want the default.
- Use TimeSpan.Zero shortcut via Empty when no elements are needed.
When it happens
Trigger: Calling AsyncObservable.Take(source, TimeSpan, null), or passing a scheduler field/property that was never initialized (e.g. a DI-resolved scheduler that is null).
Common situations: DI container not registered for IAsyncScheduler; refactoring that removed a scheduler instantiation; copying an overload call and forgetting the third argument.
Related errors
- throw new ArgumentNullException(nameof(scheduler));
- source
- 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/12e9b23ba421e9c5.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Take.cs:66
duration,
static async (source, duration, observer) =>
{
var (sourceObserver, timer) = await AsyncObserver.Take(observer, duration).ConfigureAwait(false);
var subscription = await source.SubscribeSafeAsync(sourceObserver).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, timer);
});
}
public static IAsyncObservable<TSource> Take<TSource>(this IAsyncObservable<TSource> source, TimeSpan duration, IAsyncScheduler scheduler)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (duration < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(duration));
if (scheduler == null) // REVIEW: scheduler not used.
throw new ArgumentNullException(nameof(scheduler));
if (duration == TimeSpan.Zero)
{
return Empty<TSource>();
}
// REVIEW: May be easier to just use TakeUntil with a Timer parameter. Do we want Take on the observer?
return CreateAsyncObservable<TSource>.From(
source,
(duration, scheduler),
static async (source, state, observer) =>
{
var (sourceObserver, timer) = await AsyncObserver.Take(observer, state.duration).ConfigureAwait(false);
var subscription = await source.SubscribeSafeAsync(sourceObserver).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, timer);View on GitHub (pinned to 94b5d5ab91)