dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'func')
Error message
Value cannot be null. (Parameter 'func')
What it means
System.ArgumentNullException thrown by the sync Aggregate overload of IAsyncObservable<T> when the accumulator delegate 'func' is null. The operator eagerly validates all arguments before creating the subscription pipeline, since a null accumulator would only fail mid-stream otherwise. This fail-fast style is used across all AsyncRx.NET operators.
Solutions
- Pass a non-null accumulator lambda, e.g. source.Aggregate((acc, x) => acc + x).
- If the delegate comes from a variable, check it for null before calling Aggregate and substitute a default.
- Ensure any factory/method-group expression used as 'func' actually returns a delegate instance at runtime.
Example fix
// before Func<int, int, int> acc = GetAccumulator(); // may return null var result = source.Aggregate(acc); // after var acc = GetAccumulator() ?? ((a, x) => a + x); var result = source.Aggregate(acc);
Defensive patterns
Strategy: validation
Validate before calling
if (source is null) throw new ArgumentNullException(nameof(source)); if (func is null) throw new ArgumentNullException(nameof(func)); var result = source.Aggregate(func);
Type guard
static bool IsValidAggregateArgs<TSource>(IAsyncObservable<TSource>? source, Func<TSource, TSource, TSource>? func)
=> source is not null && func is not null; Try / catch
try { var result = source.Aggregate(func); }
catch (ArgumentNullException ex) when (ex.ParamName == "func") { /* supply default accumulator */ } Prevention
- Never pass nullable delegate fields directly into operator calls; coalesce with a default.
- Prefer inline lambdas over method groups that can resolve to null.
- Enable nullable reference types (NRT) so the compiler flags nullable delegates.
When it happens
Trigger: Calling source.Aggregate(null) — i.e. invoking the two-generic-parameter Aggregate extension (Aggregate.cs:16 guard) with a null Func<TSource,TSource,TSource>.
Common situations: Passing a method group that resolves to null (e.g. a nullable static field holding a comparer/accumulator), conditional delegates assigned from configuration that was never initialized, or refactoring that removed the lambda but left the call site.
Related errors
- Value cannot be null. (Parameter 'resultSelector')
- new ArgumentNullException(nameof(comparer))
- ArgumentNullException: comparer
- Value cannot be null. (Parameter 'scheduler')
- Value cannot be null. (Parameter 'observer')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/cadfc786e0b66fba.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Aggregate.cs:16
// 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<TSource> Aggregate<TSource>(this IAsyncObservable<TSource> source, Func<TSource, TSource, TSource> func)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (func == null)
throw new ArgumentNullException(nameof(func));
return CreateAsyncObservable<TSource>.From(
source,
func,
static (source, func, observer) => source.SubscribeSafeAsync(AsyncObserver.Aggregate(observer, func)));
}
public static IAsyncObservable<TSource> Aggregate<TSource>(this IAsyncObservable<TSource> source, Func<TSource, TSource, ValueTask<TSource>> func)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (func == null)
throw new ArgumentNullException(nameof(func));
return CreateAsyncObservable<TSource>.From(
source,
func,
static (source, func, observer) => source.SubscribeSafeAsync(AsyncObserver.Aggregate(observer, func)));View on GitHub (pinned to 94b5d5ab91)