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

  1. Ensure the observable is created before counting, e.g. via AsyncObservable.Create or another operator.
  2. Null-check or coalesce the source before calling Count (e.g. source ?? AsyncObservable.Empty<T>()).
  3. 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

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


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)