dotnet/reactive · error · ArgumentNullException

throw new ArgumentNullException(nameof(other));

Error message

throw new ArgumentNullException(nameof(other));

What it means

The Timeout(source, timeoutDurationSelector, other) overload throws ArgumentNullException because the 'other' fallback sequence is null. This overload exists specifically to switch to 'other' on timeout, so it must be non-null. The check fires before any subscription, when the query is built.

Solutions

  1. Pass a non-null fallback such as Observable.Empty<TSource>() or Observable.Throw<TSource>(new TimeoutException())
  2. If no fallback is wanted, use the (source, selector) overload which throws TimeoutException instead
  3. Fix the producer that yields the null fallback stream

Example fix

// before
source.Timeout(selector, other)
// after
var fallback = other ?? Observable.Empty<TSource>();
source.Timeout(selector, fallback)
Defensive patterns

Strategy: validation

Validate before calling

var fallback = other ?? Observable.Empty<TSource>();
var result = source.Timeout(timeoutDurationSelector, fallback);

Type guard

static bool IsValidFallback<T>(IObservable<T> o) => o is not null;

Try / catch

try
{
    result = source.Timeout(selector, other);
}
catch (ArgumentNullException ex) when (ex.ParamName == "other")
{
    result = source.Timeout(selector); // TimeoutException behavior instead of fallback
}

Prevention

When it happens

Trigger: Calling source.Timeout(selector, other) with a null IObservable<TSource> fallback sequence.

Common situations: A fallback stream lazily created but never initialized; a method returning null instead of Observable.Empty; merging logic that passes an optional fallback straight through.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Time.cs:1935

        /// <param name="timeoutDurationSelector">Selector to retrieve an observable sequence that represents the timeout between the current element and the next element.</param>
        /// <param name="other">Sequence to return in case of a timeout.</param>
        /// <returns>The source sequence switching to the other sequence in case of a timeout.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="timeoutDurationSelector"/> or <paramref name="other"/> is null.</exception>
        public static IObservable<TSource> Timeout<TSource, TTimeout>(this IObservable<TSource> source, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector, IObservable<TSource> other)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (timeoutDurationSelector == null)
            {
                throw new ArgumentNullException(nameof(timeoutDurationSelector));
            }

            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            return s_impl.Timeout(source, timeoutDurationSelector, other);
        }

        /// <summary>
        /// Applies a timeout policy to the observable sequence based on an initial timeout duration for the first element, and a timeout duration computed for each subsequent element.
        /// If the next element isn't received within the computed duration starting from its predecessor, a TimeoutException is propagated to the observer.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <typeparam name="TTimeout">The type of the elements in the timeout sequences used to indicate the timeout duration for each element in the source sequence.</typeparam>
        /// <param name="source">Source sequence to perform a timeout for.</param>
        /// <param name="firstTimeout">Observable sequence that represents the timeout for the first element.</param>
        /// <param name="timeoutDurationSelector">Selector to retrieve an observable sequence that represents the timeout between the current element and the next element.</param>
        /// <returns>The source sequence with a TimeoutException in case of a timeout.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="firstTimeout"/> or <paramref name="timeoutDurationSelector"/> is null.</exception>
        public static IObservable<TSource> Timeout<TSource, TTimeout>(this IObservable<TSource> source, IObservable<TTimeout> firstTimeout, Func<TSource, IObservable<TTimeout>> timeoutDurationSelector)
        {

View on GitHub (pinned to 94b5d5ab91)