dotnet/reactive · error · ArgumentException
Strings_Core.DISPOSABLES_CANT_CONTAIN_NULL
Error message
Strings_Core.DISPOSABLES_CANT_CONTAIN_NULL
What it means
StableCompositeDisposable.Create(...) validates its collection of disposables before accepting them. If the passed enumerable contains a null element, an ArgumentException with DISPOSABLES_CANT_CONTAIN_NULL is thrown from the NAryEnumerable constructor. StableCompositeDisposable requires all elements to be non-null so Dispose can iterate and dispose every item without null checks.
Solutions
- Filter out nulls before passing: pass disposables.Where(d => d != null).
- Fix the code constructing the collection so it never produces null entries.
- Assert or log collection contents during construction to locate the null source.
Example fix
// before var composite = StableCompositeDisposable.Create(disposables); // after var composite = StableCompositeDisposable.Create(disposables.Where(d => d != null));
Defensive patterns
Strategy: validation
Validate before calling
if (disposables == null) throw new ArgumentNullException(nameof(disposables));
if (disposables.Any(d => d == null)) throw new ArgumentException("collection contains null", nameof(disposables)); Type guard
bool AllNonNull(IEnumerable<IDisposable?> xs) => xs != null && !xs.Any(d => d is null);
Try / catch
try { var c = StableCompositeDisposable.Create(disposables); } catch (ArgumentException ex) when (ex.ParamName == nameof(disposables)) { /* sanitize collection and retry */ } Prevention
- Sanitize externally sourced collections before composing disposables.
- Prefer returning Disposable.Empty over null from factory helpers.
When it happens
Trigger: Calling StableCompositeDisposable.Create(IEnumerable<IDisposable>) (the NAryEnumerable path) where the enumerable yields a null element, e.g. a List<IDisposable> with a null entry or a LINQ projection producing nulls.
Common situations: Building the collection from external or config-driven input where some entries failed to initialize; conditional assignment patterns like cond ? d : null; deserialized collections containing nulls.
Related errors
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'onNext')
- Value cannot be null. (Parameter 'onError')
- Value cannot be null. (Parameter 'disposable')
- Value cannot be null. (Parameter 'disposable')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2d153e0ac75d6eba.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Disposables/StableCompositeDisposable.cs:125
_disposable1.Dispose();
_disposable2.Dispose();
}
}
private sealed class NAryEnumerable : StableCompositeDisposable
{
private volatile List<IDisposable>? _disposables;
public NAryEnumerable(IEnumerable<IDisposable> disposables)
{
_disposables = new List<IDisposable>(disposables);
//
// Doing this on the list to avoid duplicate enumeration of disposables.
//
if (_disposables.Contains(null!))
{
throw new ArgumentException(Strings_Core.DISPOSABLES_CANT_CONTAIN_NULL, nameof(disposables));
}
}
public override bool IsDisposed => _disposables == null;
public override void Dispose()
{
var old = Interlocked.Exchange(ref _disposables, null);
if (old != null)
{
foreach (var d in old)
{
d.Dispose();
}
}
}
}
View on GitHub (pinned to 94b5d5ab91)