dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source')
Error message
Value cannot be null. (Parameter 'source')
What it means
The parameterless-projection AsyncObservable.Max<TSource>(IAsyncObservable<TSource>) throws ArgumentNullException with parameter name 'source' when the input async observable is null. The library validates all operator inputs eagerly so the failure surfaces at composition time, not later during subscription. A null source has no meaningful Max semantics, so the throw is immediate.
Solutions
- Ensure the source is created with a non-null factory such as AsyncObservable.Return(...) or AsyncObservable.Empty(...) before calling Max.
- Guard at the call site: if (source == null) source = AsyncObservable.Empty<int>();
- Use the null-coalescing operator: AsyncObservable.Max(source ?? AsyncObservable.Empty<int>())
Example fix
// before IAsyncObservable<int> source = maybeSource; // can be null var max = AsyncObservable.Max(source); // after var max = AsyncObservable.Max(source ?? AsyncObservable.Empty<int>());
Defensive patterns
Strategy: validation
Validate before calling
if (source is null) source = AsyncObservable.Empty<TSource>();
Type guard
static bool HasSource<TSource>(IAsyncObservable<TSource>? s) => s is not null;
Try / catch
try { var max = AsyncObservable.Max(source); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* substitute Empty() or fix upstream factory */ } Prevention
- Build sources only via library factories (Return/Range/Empty), never leave pipeline variables null
- Initialize IAsyncObservable fields at declaration or in constructors
- Check DI registrations for unbound IAsyncObservable dependencies
When it happens
Trigger: Calling AsyncObservable.Max(null) — typically a source variable that is null because an earlier factory/conditional expression produced null, or a method chain where the upstream Build/Return call was skipped.
Common situations: A pipeline assembled conditionally where the source assignment is missed on one branch; deserialized or DI-injected observables that failed to bind; storing IAsyncObservable in a field initialized lazily and read too early.
Related errors
- Value cannot be null. (Parameter 'comparer')
- Value cannot be null. (Parameter 'observer')
- observer
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'onNext')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/9ed9849b4e74b185.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Max.cs:15
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Max<TSource>(IAsyncObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return Create(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Max(observer)));
}
public static IAsyncObservable<TSource> Max<TSource>(IAsyncObservable<TSource> source, IComparer<TSource> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return CreateAsyncObservable<TSource>.From(
source,
comparer,
static (source, comparer, observer) => source.SubscribeSafeAsync(AsyncObserver.Max(observer, comparer)));
}
}
View on GitHub (pinned to 94b5d5ab91)