dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'right')
Error message
Value cannot be null. (Parameter 'right')
What it means
GroupJoin requires the `right` source sequence; a null right-hand observable is rejected with ArgumentNullException as the second guard in the method. Without a right sequence there is nothing to join durations against, so fail-fast is intentional.
Solutions
- Substitute AsyncObservable.Empty<TRight>() when the right stream is intentionally absent.
- Null-check/initialize the right observable before composing the join.
- Verify the factory method producing the right stream never returns null.
Example fix
// before var result = left.GroupJoin(maybeRight, lds, rds, rs); // after var result = left.GroupJoin(maybeRight ?? AsyncObservable.Empty<TRight>(), lds, rds, rs);
Defensive patterns
Strategy: validation
Validate before calling
if (right is null) throw new ArgumentNullException(nameof(right)); // or normalize: right ??= AsyncObservable.Empty<TRight>();
Type guard
bool IsValidSource<T>(IAsyncObservable<T>? s) => s is not null;
Try / catch
try
{
var result = left.GroupJoin(right, lds, rds, rs);
}
catch (ArgumentNullException ex) when (ex.ParamName == "right")
{
var result = AsyncObservable.Empty<TResult>();
} Prevention
- Substitute AsyncObservable.Empty<TRight>() when the right stream is disabled by config.
- Assert stream factories never return null; unit-test the disabled-stream path.
- Initialize right-source fields at construction, not lazily on first use.
When it happens
Trigger: Calling `left.GroupJoin(null, leftDurationSelector, rightDurationSelector, resultSelector)` or passing a null-returning right-stream factory to the static AsyncObservable.GroupJoin.
Common situations: Right stream conditionally loaded (e.g. null when a feed is disabled); config-driven stream selection returning null; refactoring that renamed the right-source variable ahead of its assignment.
Related errors
- leftDurationSelector
- rightDurationSelector
- Value cannot be null. (Parameter 'left')
- Argument cannot be null (Parameter name: functionAsync)
- Argument cannot be null (Parameter name: observer)
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/51be17d8d29d992c.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/GroupJoin.cs:20
// 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.Reactive.Subjects;
using System.Threading;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TResult> GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>(this IAsyncObservable<TLeft> left, IAsyncObservable<TRight> right, Func<TLeft, IAsyncObservable<TLeftDuration>> leftDurationSelector, Func<TRight, IAsyncObservable<TRightDuration>> rightDurationSelector, Func<TLeft, IAsyncObservable<TRight>, TResult> resultSelector)
{
if (left == null)
throw new ArgumentNullException(nameof(left));
if (right == null)
throw new ArgumentNullException(nameof(right));
if (leftDurationSelector == null)
throw new ArgumentNullException(nameof(leftDurationSelector));
if (rightDurationSelector == null)
throw new ArgumentNullException(nameof(rightDurationSelector));
if (resultSelector == null)
throw new ArgumentNullException(nameof(resultSelector));
return Create<TResult>(async observer =>
{
var subscriptions = new CompositeAsyncDisposable();
var (leftObserver, rightObserver, disposable) = AsyncObserver.GroupJoin(observer, subscriptions, leftDurationSelector, rightDurationSelector, resultSelector);
var leftSubscription = await left.SubscribeSafeAsync(leftObserver).ConfigureAwait(false);
await subscriptions.AddAsync(leftSubscription).ConfigureAwait(false);
var rightSubscription = await right.SubscribeSafeAsync(rightObserver).ConfigureAwait(false);
await subscriptions.AddAsync(rightSubscription).ConfigureAwait(false);View on GitHub (pinned to 94b5d5ab91)