dotnet/reactive · error · ArgumentNullException

ArgumentNullException

Error message

ArgumentNullException

What it means

Append concatenates a single value onto the end of an observable sequence and requires a non-null source. The public extension method validates `source` eagerly and throws ArgumentNullException before any subscription occurs.

Solutions

  1. Null-check source before calling Append.
  2. Return Observable.Empty<TSource>() from producers instead of null.
  3. Coalesce: (source ?? Observable.Empty<T>()).Append(value).

Example fix

// before
var withEnd = source.Append(lastValue);
// after
var withEnd = (source ?? Observable.Empty<int>()).Append(lastValue);
Defensive patterns

Strategy: validation

Validate before calling

if (source is null) throw new ArgumentNullException(nameof(source));

Type guard

static bool IsSource<T>(IObservable<T>? s) => s is not null;

Try / catch

try { var withEnd = source.Append(value); }
catch (ArgumentNullException ex) { logger.LogError(ex, "Append requires a non-null source"); }

Prevention

When it happens

Trigger: Calling source.Append(value) where source is null — commonly a null stream from an uninitialized variable, failed lookup, or producer returning null.

Common situations: Chaining operators off a method that returned null instead of an empty observable; event-driven streams wired up too late; deserialized configuration with a missing stream.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Single.cs:26

namespace System.Reactive.Linq
{
    public static partial class Observable
    {
        #region + Append +

        /// <summary>
        /// Append a value to an observable sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence to append the value to.</param>
        /// <param name="value">Value to append to the specified sequence.</param>
        /// <returns>The source sequence appended with the specified value.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public static IObservable<TSource> Append<TSource>(this IObservable<TSource> source, TSource value)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return s_impl.Append(source, value);
        }

        /// <summary>
        /// Append a value to an observable sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence to append the value to.</param>
        /// <param name="value">Value to append to the specified sequence.</param>
        /// <param name="scheduler">Scheduler to emit the append values on.</param>
        /// <returns>The source sequence appended with the specified value.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public static IObservable<TSource> Append<TSource>(this IObservable<TSource> source, TSource value, IScheduler scheduler)
        {
            if (source == null)
            {

View on GitHub (pinned to 94b5d5ab91)