dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'disposables')

Error message

Value cannot be null. (Parameter 'disposables')

What it means

This CompositeAsyncDisposable constructor takes a params IAsyncDisposable[] array and copies it into its internal list. Because a null array is ambiguous with an empty one and would break subsequent operations, the constructor throws ArgumentNullException for the 'disposables' parameter.

Solutions

  1. Pass a non-null array (or no arguments at all, which yields an empty composite)
  2. Default the array to Array.Empty<IAsyncDisposable>() before construction
  3. Null-check and fall back to the parameterless constructor

Example fix

// before
var composite = new CompositeAsyncDisposable(disposables); // disposables is null
// after
var composite = disposables is { Length: > 0 }
    ? new CompositeAsyncDisposable(disposables)
    : new CompositeAsyncDisposable();
Defensive patterns

Strategy: validation

Validate before calling

if (disposables == null) disposables = Array.Empty<IAsyncDisposable>();

Type guard

bool IsValidDisposables(IAsyncDisposable[]? disposables) => disposables is not null;

Try / catch

try { var c = new CompositeAsyncDisposable(disposables); } catch (ArgumentNullException ex) when (ex.ParamName == "disposables") { c = new CompositeAsyncDisposable(); }

Prevention

When it happens

Trigger: new CompositeAsyncDisposable((IAsyncDisposable[])null) — e.g. calling the params constructor with a single null-typed array argument, or passing an array variable that is null.

Common situations: An array field initialized later or returned null from a factory; a method forwarding a possibly-null array; forgetting the params overload accepts a raw null array.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Disposables/CompositeAsyncDisposable.cs:26

using System.Threading.Tasks;

namespace System.Reactive.Disposables
{
    public sealed class CompositeAsyncDisposable : IAsyncDisposable
    {
        private readonly AsyncGate _gate = new();
        private readonly List<IAsyncDisposable> _disposables;
        private bool _disposed;

        public CompositeAsyncDisposable()
        {
            _disposables = new List<IAsyncDisposable>();
        }

        public CompositeAsyncDisposable(params IAsyncDisposable[] disposables)
        {
            if (disposables == null)
                throw new ArgumentNullException(nameof(disposables));

            _disposables = new List<IAsyncDisposable>(disposables);
        }

        public CompositeAsyncDisposable(IEnumerable<IAsyncDisposable> disposables)
        {
            if (disposables == null)
                throw new ArgumentNullException(nameof(disposables));

            _disposables = new List<IAsyncDisposable>(disposables);
        }

        public async ValueTask AddAsync(IAsyncDisposable disposable)
        {
            if (disposable == null)
                throw new ArgumentNullException(nameof(disposable));

            var shouldDispose = false;

View on GitHub (pinned to 94b5d5ab91)