dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'subject')

Error message

Value cannot be null. (Parameter 'subject')

What it means

The subject parameter of Multicast is validated after the source. The IAsyncSubject<TSource, TResult> is the shared hub that multicasts source notifications to subscribers, so null is rejected immediately when the connectable is created.

Solutions

  1. Pass a valid subject such as new AsyncSubject<TSource>() or Async BehaviorSubject
  2. Fix the subject factory/DI registration that returns null
  3. Use Publish/Replay helpers instead of hand-constructing subjects when possible

Example fix

// before
source.Multicast(null);
// after
source.Multicast(new AsyncSubject<int>());
Defensive patterns

Strategy: validation

Validate before calling

if (subject == null) throw new ArgumentNullException(nameof(subject));

Type guard

bool IsValidSubject<TSource,TResult>(IAsyncSubject<TSource,TResult> s) => s is not null;

Try / catch

try { var conn = source.Multicast(subject); } catch (ArgumentNullException ex) when (ex.ParamName == "subject") { /* create a subject */ }

Prevention

When it happens

Trigger: Calling source.Multicast(null), or calling Publish/PublishLast/Replay variants whose internal subject construction returns null and is forwarded here.

Common situations: A subject factory or DI-resolved subject that returned null; using the wrong null-able type when a custom IAsyncSubject implementation was intended.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Multicast.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.Reactive.Disposables;
using System.Reactive.Subjects;
using System.Threading.Tasks;

namespace System.Reactive.Linq
{
    public partial class AsyncObservable
    {
        public static IConnectableAsyncObservable<TResult> Multicast<TSource, TResult>(this IAsyncObservable<TSource> source, IAsyncSubject<TSource, TResult> subject)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (subject == null)
                throw new ArgumentNullException(nameof(subject));

            return new ConnectableAsyncObservable<TSource, TResult>(source, subject);
        }

        public static IAsyncObservable<TSource> Multicast<TSource>(this IAsyncObservable<TSource> source, Func<IAsyncSubject<TSource>> subjectFactory)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (subjectFactory == null)
                throw new ArgumentNullException(nameof(subjectFactory));

            return Multicast(source, () => new ValueTask<IAsyncSubject<TSource, TSource>>(subjectFactory()), x => new ValueTask<IAsyncObservable<TSource>>(x));
        }

        public static IAsyncObservable<TSource> Multicast<TSource>(this IAsyncObservable<TSource> source, Func<ValueTask<IAsyncSubject<TSource>>> subjectFactory)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

View on GitHub (pinned to 94b5d5ab91)