dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'source')
Error message
Value cannot be null. (Parameter 'source')
What it means
The Buffer(count) extension validates its source IAsyncObservable<TSource> and throws ArgumentNullException('observer' wording notwithstanding, the parameter here is 'source') when null. Buffer groups elements into IList<TSource> batches of the given size, which is impossible without a source. AsyncRx.NET validates all operator inputs at composition time so failures happen where the pipeline is built, not mid-stream.
Solutions
- Ensure the expression producing the source is non-null before chaining .Buffer(count); null-check or coalesce to AsyncObservable.Empty<TSource>().
- Fix the factory/repository method that returned a null IAsyncObservable so it returns a valid (possibly empty) observable.
- Catch ArgumentNullException at the composition site to fail fast with a clearer domain message.
Example fix
// before var batches = GetObservable()?.Buffer(10); // null source when factory fails // after var src = GetObservable() ?? AsyncObservable.Empty<MyItem>(); var batches = src.Buffer(10);
Defensive patterns
Strategy: validation
Validate before calling
if (source is null) source = AsyncObservable.Empty<TSource>();
if (count <= 0) throw new ArgumentException("count must be positive", nameof(count)); Type guard
bool IsSubscribable<T>(IAsyncObservable<T>? s) => s is not null;
Try / catch
try { var batches = src.Buffer(count); }
catch (ArgumentNullException ex) { log.LogError(ex, "Buffer composition failed: {Param}", ex.ParamName); throw; } Prevention
- Coalesce null observables with AsyncObservable.Empty<T>() before chaining operators
- Make factories return non-null (possibly empty) observables rather than null
- Enable nullable reference types to catch null sources at compile time
When it happens
Trigger: Calling source.Buffer(count) where source is null — e.g. a method returning IAsyncObservable<T> that returned null on an error path, an uninitialized field, or a null result from a lookup/conditional factory before chaining .Buffer(n).
Common situations: Conditional observable creation (returning null instead of AsyncObservable.Empty<T>()); refactoring that removed the assignment feeding the variable; optional configuration where the observable is only set in some environments.
Related errors
- Value cannot be null. (Parameter 'count')
- Value cannot be null. (Parameter 'skip')
- Value cannot be null. (Parameter 'timeSpan')
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/4b71eb19024909d1.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs:18
// 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.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Threading;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, int count)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (count <= 0)
throw new ArgumentNullException(nameof(count));
return CreateAsyncObservable<IList<TSource>>.From(
source,
count,
static (source, count, observer) => source.SubscribeSafeAsync(AsyncObserver.Buffer(observer, count)));
}
public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, int count, int skip)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (count <= 0)
throw new ArgumentNullException(nameof(count));
if (skip <= 0)
throw new ArgumentNullException(nameof(skip));
View on GitHub (pinned to 94b5d5ab91)