dotnet/reactive · error · ArgumentNullException

Thrown when onCompleted is null (ArgumentNullException…

Error message

Thrown when onCompleted is null (ArgumentNullException, param name: onCompleted)

What it means

The three-callback Do overload requires a non-null onCompleted action and throws ArgumentNullException with parameter name 'onCompleted'. onCompleted runs on successful termination of the sequence; the library rejects null eagerly so the mistake is caught at the call site, not during enumeration.

Solutions

  1. Pass a no-op `() => { }` for onCompleted
  2. Use the Do(source, onNext, onError) overload, which supplies an internal no-op completion handler
  3. Default it: `onCompleted ??= () => { };` before the call
  4. Implement completion handling via other operators (e.g. a Finally-style construct) if that fits better

Example fix

// before
var result = source.Do(x => Log(x), e => Log(e), null);
// after
var result = source.Do(x => Log(x), e => Log(e), () => { });
Defensive patterns

Strategy: validation

Validate before calling

if (onCompleted is null) onCompleted = static () => { };

Type guard

static Action NonNullCompleted(Action? h) => h ?? (static () => { });

Try / catch

try { var result = source.Do(x => Log(x), e => Log(e), onCompleted!); ... }
catch (ArgumentNullException ex) when (ex.ParamName == "onCompleted") { Log("onCompleted callback missing; using no-op"); }

Prevention

When it happens

Trigger: `source.Do(x => Log(x), e => Log(e), null)`; a completion callback omitted because it seemed optional; a variable assigned only in some code path.

Common situations: Teardown/dispose logic left unwired; pipelines where completion handling was added later but the argument was stubbed null; optional callbacks from configuration.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/e875431c6fadd214. Report an issue: GitHub.

Appendix: source

Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/Do.cs:87

        /// Lazily invokes an action for each value in the sequence, and executes an action upon successful or exceptional
        /// 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="onError">Action to invoke on exceptional termination of the sequence.</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<Exception> onError, Action onCompleted)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (onNext == null)
                throw new ArgumentNullException(nameof(onNext));
            if (onError == null)
                throw new ArgumentNullException(nameof(onError));
            if (onCompleted == null)
                throw new ArgumentNullException(nameof(onCompleted));

            return DoCore(source, onNext, onError, onCompleted);
        }

        /// <summary>
        /// Lazily invokes observer methods for each value in the sequence, and upon successful or exceptional termination.
        /// </summary>
        /// <typeparam name="TSource">Source sequence element type.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="observer">Observer to invoke notification calls on.</param>
        /// <returns>Sequence exhibiting the side-effects of observer method invocation upon enumeration.</returns>
        public static IEnumerable<TSource> Do<TSource>(this IEnumerable<TSource> source, IObserver<TSource> observer)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));

View on GitHub (pinned to 94b5d5ab91)