{"record":{"id":"f7b3d46e5ac2c6bb","repo":"AvaloniaUI/Avalonia","slug":"disposables-can-t-contain-null","errorCode":null,"errorMessage":"Disposables can't contain null","messagePattern":"Disposables can't contain null","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Reactive/CompositeDisposable.cs","lineNumber":88,"sourceCode":"\n    private static List<IDisposable?> ToList(IEnumerable<IDisposable> disposables)\n    {\n        var capacity = disposables switch\n        {\n            IDisposable[] a => a.Length,\n            ICollection<IDisposable> c => c.Count,\n            _ => 12\n        };\n\n        var list = new List<IDisposable?>(capacity);\n\n        // do the copy and null-check in one step to avoid a\n        // second loop for just checking for null items\n        foreach (var d in disposables)\n        {\n            if (d == null)\n            {\n                throw new ArgumentException(\"Disposables can't contain null\", nameof(disposables));\n            }\n\n            list.Add(d);\n        }\n\n        return list;\n    }\n\n    /// <summary>\n    /// Gets the number of disposables contained in the <see cref=\"CompositeDisposable\"/>.\n    /// </summary>\n    public int Count => Volatile.Read(ref _count);\n\n    /// <summary>\n    /// Adds a disposable to the <see cref=\"CompositeDisposable\"/> or disposes the disposable if the <see cref=\"CompositeDisposable\"/> is disposed.\n    /// </summary>\n    /// <param name=\"item\">Disposable to add.</param>\n    /// <exception cref=\"ArgumentNullException\"><paramref name=\"item\"/> is <c>null</c>.</exception>","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Reactive/CompositeDisposable.cs#L70-L106","documentation":"CompositeDisposable.ToList helper copies the source disposables and, per the doc contract, throws ArgumentException('Disposables can't contain null', nameof(disposables)) if any element is null. The copy and null-check are fused into one loop for efficiency. This enforces the invariant that the composite never stores null disposables.","triggerScenarios":"Constructing CompositeDisposable with any collection (params array or IList) whose enumeration contains at least one null element, e.g. new CompositeDisposable(d1, null, d3).","commonSituations":"A disposable returned null from a factory (e.g. a subscribe that returned null), a LINQ Select producing nulls, or an array initializer with an accidental null slot.","solutions":["Filter nulls before construction: disposables.Where(d => d is not null).","Fix the producing code so it never returns null disposables.","If an absent disposable is legitimate, substitute Disposable.Empty rather than null."],"exampleFix":"// before\nvar cd = new CompositeDisposable(maybeWithNulls);\n\n// after\nvar cd = new CompositeDisposable(maybeWithNulls.Where(d => d is not null).ToArray());","handlingStrategy":"validation","validationCode":"var clean = disposables.Where(d => d is not null).ToArray();\nvar cd = new CompositeDisposable(clean);","typeGuard":"bool NoNulls(IEnumerable<IDisposable?> ds) => ds.All(d => d is not null);","tryCatchPattern":null,"preventionTips":["Filter nulls out of disposable collections before construction.","Fix factories that return null disposables; substitute Disposable.Empty.","Add an Assert.All(items, i => Assert.NotNull(i)) in tests."],"tags":["avalonia","reactive","disposables","argument","null-element"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}