dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'disposable')
Error message
Value cannot be null. (Parameter 'disposable')
What it means
CompositeAsyncDisposable.AddAsync registers an IAsyncDisposable to be disposed when the composite is disposed. A null argument is rejected immediately with ArgumentNullException naming 'disposable', because the composite would otherwise throw during DisposeAsync when iterating its children.
Solutions
- Ensure a non-null IAsyncDisposable is produced before calling AddAsync
- Skip the AddAsync call when the value is null
- Substitute AsyncDisposable.Nop for a null disposable
Example fix
// before
var d = CreateResource(); // may return null
await composite.AddAsync(d);
// after
var d = CreateResource();
if (d != null)
await composite.AddAsync(d); Defensive patterns
Strategy: type-guard
Validate before calling
if (disposable != null) await composite.AddAsync(disposable);
Type guard
bool IsAddable(IAsyncDisposable? disposable) => disposable is not null;
Try / catch
try { await composite.AddAsync(disposable); } catch (ArgumentNullException ex) when (ex.ParamName == "disposable") { await composite.AddAsync(AsyncDisposable.Nop); } Prevention
- Guard factory results for null before adding to a composite
- Substitute AsyncDisposable.Nop for optional disposables
- Avoid methods that return null disposables; return Nop or throw at the source
When it happens
Trigger: await composite.AddAsync(null) — typically a factory/method that returned null instead of a disposable, or a nullable field not yet initialized.
Common situations: Conditional resource creation that skips assignment; passing the result of a TryGet-style API that yields null; refactoring where a disposable was removed but call sites still add it.
Related errors
- Value cannot be null. (Parameter 'disposables')
- Value cannot be null. (Parameter 'subscribeAsync')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'source')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/ddcbf01e9de50cf7.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Disposables/CompositeAsyncDisposable.cs:42
{
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;
using (await _gate.LockAsync().ConfigureAwait(false))
{
if (_disposed)
{
shouldDispose = true;
}
else
{
_disposables.Add(disposable);
}
}
if (shouldDispose)
{
await disposable.DisposeAsync().ConfigureAwait(false);View on GitHub (pinned to 94b5d5ab91)