dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source')
Error message
Value cannot be null. (Parameter 'source')
What it means
The parameterless Count extension throws ArgumentNullException because the IAsyncObservable<TSource> source is null. AsyncRx.NET extensions validate the source before subscribing so you get the error at the Count() call site rather than deep inside the async subscription. Counting requires a source stream to iterate.
Solutions
- Ensure the observable is created before counting, e.g. via AsyncObservable.Create or another operator.
- Null-check or coalesce the source before calling Count (e.g. source ?? AsyncObservable.Empty<T>()).
- Trace the factory method that produced the source and fix its null return path.
Example fix
// before
var count = await possiblyNullSource.Count();
// after
if (possiblyNullSource == null) throw new InvalidOperationException("source not initialized");
var count = await possiblyNullSource.Count(); Defensive patterns
Strategy: validation
Validate before calling
if (source is null) throw new InvalidOperationException("Source observable was not initialized before Count()."); Type guard
static bool HasSource<T>(IAsyncObservable<T>? s) => s is not null;
Try / catch
try { var n = await source.Count(); } catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* fix source initialization */ } Prevention
- Treat null observables as bugs; have factories throw rather than return null.
- Use nullable reference types to catch uninitialized source fields at compile time.
- Coalesce to AsyncObservable.Empty<T>() only when null legitimately means 'no data'.
When it happens
Trigger: Calling source.Count() where source came from a failed factory, an unassigned field, or a method that returned null.
Common situations: Chaining operators after a method that conditionally returns null; a cached observable that was never initialized; refactoring where the source creation line was removed.
Related errors
- ArgumentNullException(nameof(source))
- Value cannot be null. (Parameter 'disposable1')
- Value cannot be null. (Parameter 'disposable2')
- Value cannot be null. (Parameter 'onNextAsync')
- Value cannot be null. (Parameter 'source')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/cf14b93f96a40ffd.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Count.cs:14
// 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.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<int> Count<TSource>(this IAsyncObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return Create<TSource, int>(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Count<TSource>(observer)));
}
public static IAsyncObservable<int> Count<TSource>(this IAsyncObservable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (predicate == null)
throw new ArgumentNullException(nameof(predicate));
return CreateAsyncObservable<int>.From(
source,
predicate,
static (source, predicate, observer) => source.SubscribeSafeAsync(AsyncObserver.Count(observer, predicate)));
}
public static IAsyncObservable<int> Count<TSource>(this IAsyncObservable<TSource> source, Func<TSource, ValueTask<bool>> predicate)View on GitHub (pinned to 94b5d5ab91)