dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'onNext')
Error message
Value cannot be null. (Parameter 'onNext')
What it means
Do(source, onNext) requires a non-null Action<TSource> and throws ArgumentNullException with parameter name 'onNext' when it is null. The onNext delegate is the essence of the operator, so it is validated eagerly at call time. Without this check the failure would only appear as a NullReferenceException on the first enumerated element.
Solutions
- Provide a real action, or pass a no-op: onNext ?? (_ => { }) when the callback is genuinely optional.
- If no per-element action is needed, drop the Do operator entirely.
- Null-check the delegate at your boundary and throw with context.
- Fix the delegate producer (DI registration, registry, config) that returned null.
Example fix
// before var logged = seq.Do(_loggerHook); // _loggerHook null when logging disabled // after var logged = _loggerHook != null ? seq.Do(_loggerHook) : seq;
Defensive patterns
Strategy: validation
Validate before calling
if (onNext is null)
{
// skip Do entirely when there is no per-element action
}
else
{
var result = source.Do(onNext);
} Type guard
static bool HasAction<T>(Action<T>? a) => a is not null;
Try / catch
try
{
var result = source.Do(onNext);
}
catch (ArgumentNullException ex) when (ex.ParamName == "onNext")
{
result = source; // no per-element side effect needed
} Prevention
- Only compose Do when you actually have an action; conditionally apply it
- Default optional callbacks to no-ops rather than null
- Never pass nullable delegate fields straight into operators
- Make hook registrations explicit so missing hooks fail at configuration time
When it happens
Trigger: Passing a null Action<TSource> — e.g. an optional observer callback variable never assigned, a conditional expression yielding null, or forwarding a null optional parameter into Do.
Common situations: Configurable logging hooks where the action is optional and forwarded raw, event-handler fields not yet wired, dynamic pipelines built from a delegate registry with missing entries.
Related errors
- Value cannot be null. (Parameter 'comparer')
- Value cannot be null. (Parameter 'keySelector')
- Value cannot be null. (Parameter 'source')
- Thrown when source is null (ArgumentNullException, param…
- Thrown when source is null (ArgumentNullException, param…
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/63fc061ed4cf08c5.
Report an issue: GitHub.
Appendix: source
Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs:23
using System.Collections.Generic;
namespace System.Linq
{
public static partial class EnumerableEx
{
/// <summary>
/// Lazily invokes an action for each value in the sequence.
/// </summary>
/// <typeparam name="TSource">Source sequence element type.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="onNext">Action to invoke for each element.</param>
/// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>
public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, Action<TSource> onNext)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onNext == null)
throw new ArgumentNullException(nameof(onNext));
return DoCore(source, onNext, _ => { }, () => { });
}
/// <summary>
/// Lazily invokes an action for each value in the sequence, and executes an action for successful termination.
/// </summary>
/// <typeparam name="TSource">Source sequence element type.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="onNext">Action to invoke for each element.</param>
/// <param name="onCompleted">Action to invoke on successful termination of the sequence.</param>
/// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>
public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, Action<TSource> onNext, Action onCompleted)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onNext == null)
throw new ArgumentNullException(nameof(onNext));View on GitHub (pinned to 94b5d5ab91)