dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'exception')

Error message

Value cannot be null. (Parameter 'exception')

What it means

Throw<TResult>(exception) creates a sequence that throws the given exception when enumerated. Because the whole point is to throw a caller-supplied exception, a null exception is meaningless; the factory validates it eagerly and throws ArgumentNullException naming `exception`.

Solutions

  1. Ensure a concrete Exception instance is passed, e.g. `Throw<int>(new InvalidOperationException("...")`.
  2. If the exception variable may be null, fall back to a default exception: `ex ?? new Exception("unknown")`.
  3. Rework the pipeline to only enter the Throw path when an exception was actually captured.
  4. For deferred failure, consider Task/async compositions that carry failure natively instead of a null placeholder.

Example fix

// before
return Throw<int>(lastError);
// after
return Throw<int>(lastError ?? new InvalidOperationException("Operation failed with no details."));
Defensive patterns

Strategy: validation

Validate before calling

if (exception is null) throw new ArgumentNullException(nameof(exception));
// or: var ex2 = exception ?? new InvalidOperationException("no details");

Type guard

static bool IsValidException(Exception e) => e is not null;

Try / catch

try { var seq = Throw<T>(captured); }
catch (ArgumentNullException ex) when (ex.ParamName == "exception") { /* supply a fallback exception */ }

Prevention

When it happens

Trigger: Calling `Throw<MyType>(null)`, e.g. rethrowing a captured exception variable that turned out to be null, or forwarding `ex` from a handler that received null.

Common situations: Generic error-propagation pipelines where the captured Exception field/property defaults to null, building a stream of failures from nullable exception state (e.g. Task.Exception before fault).

Related errors


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

Appendix: source

Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/Throw.cs:20

// 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;

namespace System.Linq
{
    public static partial class EnumerableEx
    {
        /// <summary>
        /// Returns a sequence that throws an exception upon enumeration.
        /// </summary>
        /// <typeparam name="TResult">Result sequence element type.</typeparam>
        /// <param name="exception">Exception to throw upon enumerating the resulting sequence.</param>
        /// <returns>Sequence that throws the specified exception upon enumeration.</returns>
        public static IEnumerable<TResult> Throw<TResult>(Exception exception)
        {
            if (exception == null)
                throw new ArgumentNullException(nameof(exception));

            return ThrowCore<TResult>(exception);
        }

        private static IEnumerable<TResult> ThrowCore<TResult>(Exception exception)
        {
            throw exception;
#pragma warning disable CS0162 // Unreachable code detected
            yield break;
#pragma warning restore CS0162 // Unreachable code detected
        }
    }
}

View on GitHub (pinned to 94b5d5ab91)