dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'source')

Error message

Value cannot be null. (Parameter 'source')

What it means

Multicast connects an IAsyncObservable to an IAsyncSubject to produce an IConnectableAsyncObservable. A null source observable leaves the connectable with nothing to subscribe to, so the extension method throws ArgumentNullException eagerly.

Solutions

  1. Ensure the source observable is created before calling Multicast
  2. Check the code path producing the source for a null return
  3. Guard with a fallback empty observable if null sources are expected

Example fix

// before
IAsyncObservable<int> src = GetSource(); // may return null
src.Multicast(new AsyncSubject<int>());
// after
var src = GetSource() ?? AsyncObservable.Empty<int>();
src.Multicast(new AsyncSubject<int>());
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

bool IsValidSource<TSource>(IAsyncObservable<TSource> s) => s is not null;

Try / catch

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

Prevention

When it happens

Trigger: Calling source.Multicast(subject) where the IAsyncObservable<TSource> is null; calling Publish/PublishLast/Replay (which delegate to Multicast) on a null source.

Common situations: Chaining off a factory method that returned null; conditional observable construction where one branch yields null; forgetting to assign the result of an async observable builder.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Multicast.cs:16

// 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)
        {

View on GitHub (pinned to 94b5d5ab91)