dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'disposables')

Error message

Value cannot be null. (Parameter 'disposables')

What it means

CompositeDisposable's params IDisposable[] constructor first checks the whole array for null before processing its items. Passing a null array gives the composite nothing to hold, so ArgumentNullException with parameter name 'disposables' is thrown.

Solutions

  1. Ensure the array is non-null before constructing: disposableArray ??= Array.Empty<IDisposable>()
  2. If you may pass zero items, prefer new CompositeDisposable() or an empty array
  3. If passing a possibly-null single disposable, guard it first or filter it out

Example fix

// before
var cd = new CompositeDisposable(GetDisposables()); // may return null
// after
var items = GetDisposables() ?? Array.Empty<IDisposable>();
var cd = new CompositeDisposable(items);
Defensive patterns

Strategy: type-guard

Validate before calling

if (disposables == null) disposables = Array.Empty<IDisposable>();
var cd = new CompositeDisposable(disposables);

Type guard

bool IsUsableArray(IDisposable[]? a) => a is { Length: > 0 };

Try / catch

try { return new CompositeDisposable(arr); }
catch (ArgumentNullException) { return new CompositeDisposable(); }

Prevention

When it happens

Trigger: new CompositeDisposable(null) or new CompositeDisposable(someNullArray) — commonly when the array is the result of a lookup/transform that returned null, or when calling with a single null argument that binds to the params overload.

Common situations: Passing an uninitialized IDisposable[] field; calling CompositeDisposable(MaybeNullDisposable()) intending the single-item overload but hitting the params overload with null; LINQ/ToArray results assumed non-null.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Disposables/CompositeDisposable.cs:68

            if (capacity < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(capacity));
            }

            _disposables = new List<IDisposable?>(capacity);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CompositeDisposable"/> class from a group of disposables.
        /// </summary>
        /// <param name="disposables">Disposables that will be disposed together.</param>
        /// <exception cref="ArgumentNullException"><paramref name="disposables"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Any of the disposables in the <paramref name="disposables"/> collection is <c>null</c>.</exception>
        public CompositeDisposable(params IDisposable[] disposables)
        {
            if (disposables == null)
            {
                throw new ArgumentNullException(nameof(disposables));
            }

            (_disposables, _) = ToListOrDictionary(disposables);

            // _count can be read by other threads and thus should be properly visible
            // also releases the _disposables contents so it becomes thread-safe
            Volatile.Write(ref _count, disposables.Length);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CompositeDisposable"/> class from a group of disposables.
        /// </summary>
        /// <param name="disposables">Disposables that will be disposed together.</param>
        /// <exception cref="ArgumentNullException"><paramref name="disposables"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Any of the disposables in the <paramref name="disposables"/> collection is <c>null</c>.</exception>
        public CompositeDisposable(IEnumerable<IDisposable> disposables)
        {
            if (disposables == null)

View on GitHub (pinned to 94b5d5ab91)