{"record":{"id":"384804e8e76466a3","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-disposables","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'disposables')","messagePattern":"Value cannot be null\\. \\(Parameter 'disposables'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Disposables/CompositeAsyncDisposable.cs","lineNumber":26,"sourceCode":"using System.Threading.Tasks;\n\nnamespace System.Reactive.Disposables\n{\n    public sealed class CompositeAsyncDisposable : IAsyncDisposable\n    {\n        private readonly AsyncGate _gate = new();\n        private readonly List<IAsyncDisposable> _disposables;\n        private bool _disposed;\n\n        public CompositeAsyncDisposable()\n        {\n            _disposables = new List<IAsyncDisposable>();\n        }\n\n        public CompositeAsyncDisposable(params IAsyncDisposable[] disposables)\n        {\n            if (disposables == null)\n                throw new ArgumentNullException(nameof(disposables));\n\n            _disposables = new List<IAsyncDisposable>(disposables);\n        }\n\n        public CompositeAsyncDisposable(IEnumerable<IAsyncDisposable> disposables)\n        {\n            if (disposables == null)\n                throw new ArgumentNullException(nameof(disposables));\n\n            _disposables = new List<IAsyncDisposable>(disposables);\n        }\n\n        public async ValueTask AddAsync(IAsyncDisposable disposable)\n        {\n            if (disposable == null)\n                throw new ArgumentNullException(nameof(disposable));\n\n            var shouldDispose = false;","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Disposables/CompositeAsyncDisposable.cs#L8-L44","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a non-null array (or no arguments at all, which yields an empty composite)","Default the array to Array.Empty<IAsyncDisposable>() before construction","Null-check and fall back to the parameterless constructor"],"exampleFix":"// before\nvar composite = new CompositeAsyncDisposable(disposables); // disposables is null\n// after\nvar composite = disposables is { Length: > 0 }\n    ? new CompositeAsyncDisposable(disposables)\n    : new CompositeAsyncDisposable();","handlingStrategy":"validation","validationCode":"if (disposables == null) disposables = Array.Empty<IAsyncDisposable>();","typeGuard":"bool IsValidDisposables(IAsyncDisposable[]? disposables) => disposables is not null;","tryCatchPattern":"try { var c = new CompositeAsyncDisposable(disposables); } catch (ArgumentNullException ex) when (ex.ParamName == \"disposables\") { c = new CompositeAsyncDisposable(); }","preventionTips":["Call the params constructor with zero arguments for an empty composite","Coalesce arrays with Array.Empty<IAsyncDisposable>() before construction","Avoid methods returning null arrays; return empty arrays instead"],"tags":["argument-null","composite-disposable"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}