dotnet/reactive · error · ArgumentNullException

null (Parameter 'values')

Error message

null (Parameter 'values')

What it means

The params-array Append overload (IAsyncObserver, params TSource[]) treats the values array as required: it is enumerated and forwarded to the observer after the source completes. A null array (which is what you get when you explicitly pass null for the params parameter) is rejected with ArgumentNullException in the short message form ("null (Parameter 'values')").

Solutions

  1. Pass an actual array (possibly empty) — e.g. Append(observer, Array.Empty<TSource>()) or simply omit the argument to append nothing.
  2. Coalesce at the call site: Append(observer, values ?? Array.Empty<TSource>()).
  3. Fix the producer of the array so it returns an empty collection instead of null.

Example fix

// before
AsyncObservable.Append(observer, (int[])null);
// after
AsyncObservable.Append(observer, values ?? Array.Empty<int>());
Defensive patterns

Strategy: validation

Validate before calling

if (values is null) values = Array.Empty<TSource>();
var appended = AsyncObservable.Append(observer, values);

Type guard

bool HasValues<T>(T[]? v) => v is not null; // note: empty array is valid, null is not

Try / catch

try { var appended = AsyncObservable.Append(observer, values); }
catch (ArgumentNullException ex) when (ex.ParamName == "values") { var appended = AsyncObservable.Append(observer, Array.Empty<TSource>()); }

Prevention

When it happens

Trigger: Calling AsyncObservable.Append(observer, null) where null is bound to the params TSource[] values parameter (note: Append(observer) alone is legal because params allows zero values, but Append(observer, (int[])null) throws).

Common situations: Building the values list dynamically and passing a null array variable; calling Append through reflection/delegates that bypass params expansion and pass a null array; generic helper code forwarding an uninitialized array.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Append.cs:188

                                {
                                    await observer.OnNextAsync(value).RendezVous(scheduler, ct);
                                    await observer.OnCompletedAsync().RendezVous(scheduler, ct);
                                }
                            }).ConfigureAwait(false);

                            await d.AssignAsync(task).ConfigureAwait(false);
                        }
                    ),
                    d
                );
        }

        public static IAsyncObserver<TSource> Append<TSource>(IAsyncObserver<TSource> observer, params TSource[] values)
        {
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));
            if (values == null)
                throw new ArgumentNullException(nameof(values));

            return Create<TSource>(
                observer.OnNextAsync,
                observer.OnErrorAsync,
                async () =>
                {
                    foreach (var value in values)
                    {
                        await observer.OnNextAsync(value).ConfigureAwait(false);
                    }

                    await observer.OnCompletedAsync().ConfigureAwait(false);
                }
            );
        }

        public static (IAsyncObserver<TSource>, IAsyncDisposable) Append<TSource>(IAsyncObserver<TSource> observer, IAsyncScheduler scheduler, params TSource[] values)
        {

View on GitHub (pinned to 94b5d5ab91)