dotnet/reactive · error · ArgumentNullException

ArgumentNullException

Error message

ArgumentNullException

What it means

TakeUntil(source, other) validates both arguments and throws ArgumentNullException; at line 838 the failing check is 'source' being null. Rx throws eagerly so callers learn immediately that the query was built with an invalid sequence.

Solutions

  1. Ensure the source sequence is non-null before chaining TakeUntil
  2. Substitute Observable.Empty<TSource>() for missing sources when a sequence is legitimately absent
  3. Fix the upstream producer that returned null

Example fix

// before
IObservable<Event> src = _bus?.Events;
var clipped = src.TakeUntil(stopSignal);
// after
IObservable<Event> src = _bus?.Events ?? Observable.Empty<Event>();
var clipped = src.TakeUntil(stopSignal);
Defensive patterns

Strategy: validation

Validate before calling

if (source is null) throw new InvalidOperationException("source sequence required"); // or source ??= Observable.Empty<TSource>();

Type guard

static bool CanTakeUntil<TSource,TOther>(IObservable<TSource> source, IObservable<TOther> other) => source is not null;

Try / catch

try { var q = source.TakeUntil(other); }
catch (ArgumentNullException ex) when (ex.ParamName == "source") { /* fall back to empty sequence */ }

Prevention

When it happens

Trigger: Calling `.TakeUntil(other)` on a null source observable, e.g. `IObservable<int> src = null; src.TakeUntil(other);`.

Common situations: Building pipelines where the source comes from a nullable field, event registration that failed silently, or a factory that returns null instead of Observable.Empty.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs:838

        #endregion

        #region + TakeUntil +

        /// <summary>
        /// Returns the elements from the source observable sequence until the other observable sequence produces an element.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <typeparam name="TOther">The type of the elements in the other sequence that indicates the end of take behavior.</typeparam>
        /// <param name="source">Source sequence to propagate elements for.</param>
        /// <param name="other">Observable sequence that terminates propagation of elements of the source sequence.</param>
        /// <returns>An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="other"/> is null.</exception>
        public static IObservable<TSource> TakeUntil<TSource, TOther>(this IObservable<TSource> source, IObservable<TOther> other)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

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

            return s_impl.TakeUntil(source, other);
        }

        /// <summary>
        /// Relays elements from the source observable sequence and calls the predicate after an
        /// emission to check if the sequence should stop after that specific item.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source and result sequences.</typeparam>
        /// <param name="source">The source sequence to relay elements of.</param>
        /// <param name="stopPredicate">Called after each upstream item has been emitted with
        /// that upstream item and should return <code>true</code> to indicate the sequence should

View on GitHub (pinned to 94b5d5ab91)