dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'compositeDisposable')

Error message

Value cannot be null. (Parameter 'compositeDisposable')

What it means

The DisposeWith extension method throws ArgumentNullException when the compositeDisposable argument is null. DisposeWith adds the item to the given CompositeDisposable and returns it for fluent chaining; a null composite has nowhere to register the item, so it fails fast. Note the item itself may be null-tolerant in Add, but the composite cannot be null.

Solutions

  1. Initialize the CompositeDisposable at field declaration: private readonly CompositeDisposable _disposables = new();
  2. Ensure construction order assigns the composite before any DisposeWith calls.
  3. Guard the call site: if (composite != null) item.DisposeWith(composite); or keep a non-null composite through the object's lifetime and Clear() instead of nulling it.

Example fix

// before
private CompositeDisposable _disposables; // assigned later
...
subscription.DisposeWith(_disposables); // NRE/ ArgumentNullException
// after
private readonly CompositeDisposable _disposables = new CompositeDisposable();
...
subscription.DisposeWith(_disposables);
Defensive patterns

Strategy: validation

Validate before calling

if (composite == null) throw new InvalidOperationException("CompositeDisposable not initialized");
item.DisposeWith(composite);

Type guard

bool CanDisposeWith<T>(T item, CompositeDisposable c) where T : IDisposable => item != null && c != null;

Try / catch

try { item.DisposeWith(composite); } catch (ArgumentNullException ex) when (ex.ParamName == "compositeDisposable") { /* log wiring failure */ }

Prevention

When it happens

Trigger: someDisposable.DisposeWith(null), usually when the composite is a field/property that was not yet initialized (null before constructor wiring completes) or was set to null after disposal.

Common situations: Fluent subscription wiring in DI-scoped services where the CompositeDisposable is injected or created lazily; ordering bugs where DisposeWith runs before the composite field is assigned.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Disposables/Fluent/DisposableExtensions.cs:32

    /// </summary>
    /// <typeparam name="T">
    /// The type of the disposable.
    /// </typeparam>
    /// <param name="item">
    /// The disposable we are going to want to be disposed by the CompositeDisposable.
    /// </param>
    /// <param name="compositeDisposable">
    /// The <see cref="CompositeDisposable"/> to which <paramref name="item"/> will be added.
    /// </param>
    /// <returns>
    /// The disposable.
    /// </returns>
    public static T DisposeWith<T>(this T item, CompositeDisposable compositeDisposable)
        where T : IDisposable
    {
        if (compositeDisposable == null)
        {
            throw new ArgumentNullException(nameof(compositeDisposable));
        }

        compositeDisposable.Add(item);
        return item;
    }
}

View on GitHub (pinned to 94b5d5ab91)