dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'first')
Error message
Value cannot be null. (Parameter 'first')
What it means
AsyncObservable.Concat<TSource>(first, second) requires both source observables to be non-null and throws ArgumentNullException naming 'first' when the first one is null. This is an eager, fail-fast guard so you never get a null-dereference deep inside the subscription pipeline later.
Solutions
- Pass a non-null IAsyncObservable<TSource> as the first argument
- If a value can legitimately be absent, substitute AsyncObservable.Empty<TSource>() instead of null
- Check the expression producing 'first' for unintended null returns (failed lookups, unassigned fields)
Example fix
// before var result = firstSource.Concat(secondSource); // firstSource is null // after var result = (firstSource ?? AsyncObservable.Empty<int>()).Concat(secondSource);
Defensive patterns
Strategy: validation
Validate before calling
if (first is null) throw new ArgumentNullException(nameof(first)); // or ensure before call: first ??= AsyncObservable.Empty<T>();
Type guard
public static bool IsNotNullSource<T>(IAsyncObservable<T>? s) => s is not null;
Try / catch
try { var result = first.Concat(second); }
catch (ArgumentNullException ex) when (ex.ParamName == "first") { /* supply a valid source or Empty<T>() */ } Prevention
- Treat IAsyncObservable parameters as non-nullable and enable C# nullable reference types
- Substitute AsyncObservable.Empty<T>() instead of null for absent sequences
- Null-check inputs at pipeline boundaries before composing operators
When it happens
Trigger: Calling Concat with a null first argument, e.g. AsyncObservable.Concat(null, second), often because an expression or dictionary lookup that was supposed to produce the first observable returned null.
Common situations: Chaining Concat in a LINQ-style pipeline where a factory method or conditional returned null instead of an empty observable; refactors where a variable became nullable; test setups that pass null placeholders.
Related errors
- Value cannot be null. (Parameter 'second')
- Value cannot be null. (Parameter 'sources')
- Value cannot be null. (Parameter 'handlers')
- Value cannot be null. (Parameter 'disposable1')
- Value cannot be null. (Parameter 'disposable2')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/233737f5713cf5d0.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Concat.cs:18
// Licensed to the .NET Foundation under one or more agreements.
// 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;
using System.Reactive.Disposables;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
// TODO: Implement tail call behavior to flatten Concat chains.
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Concat<TSource>(this IAsyncObservable<TSource> first, IAsyncObservable<TSource> second)
{
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
throw new ArgumentNullException(nameof(second));
return Create(
first,
second,
static async (first, second, observer) =>
{
var (sink, inner) = AsyncObserver.Concat(observer, second);
var subscription = await first.SubscribeSafeAsync(sink).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, inner);
});
}
public static IAsyncObservable<TSource> Concat<TSource>(params IAsyncObservable<TSource>[] sources) => Concat((IEnumerable<IAsyncObservable<TSource>>)sources);
View on GitHub (pinned to 94b5d5ab91)