{"record":{"id":"09b6785e06b56968","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-disposable-09b678","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'disposable')","messagePattern":"Value cannot be null\\. \\(Parameter 'disposable'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Disposables/ScheduledDisposable.cs","lineNumber":25,"sourceCode":"namespace System.Reactive.Disposables\n{\n    /// <summary>\n    /// Represents a disposable resource whose disposal invocation will be scheduled on the specified <seealso cref=\"IScheduler\"/>.\n    /// </summary>\n    public sealed class ScheduledDisposable : ICancelable\n    {\n        private SingleAssignmentDisposableValue _disposable;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"ScheduledDisposable\"/> class that uses an <see cref=\"IScheduler\"/> on which to dispose the disposable.\n        /// </summary>\n        /// <param name=\"scheduler\">Scheduler where the disposable resource will be disposed on.</param>\n        /// <param name=\"disposable\">Disposable resource to dispose on the given scheduler.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"scheduler\"/> or <paramref name=\"disposable\"/> is null.</exception>\n        public ScheduledDisposable(IScheduler scheduler, IDisposable disposable)\n        {\n            Scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler));\n            _disposable.Disposable = disposable ?? throw new ArgumentNullException(nameof(disposable));\n        }\n\n        /// <summary>\n        /// Gets the scheduler where the disposable resource will be disposed on.\n        /// </summary>\n        public IScheduler Scheduler { get; }\n\n        /// <summary>\n        /// Gets the underlying disposable. After disposal, the result is undefined.\n        /// </summary>\n        public IDisposable Disposable => _disposable.Disposable ?? Disposables.Disposable.Empty;\n\n        /// <summary>\n        /// Gets a value that indicates whether the object is disposed.\n        /// </summary>\n        public bool IsDisposed => _disposable.IsDisposed;\n\n        /// <summary>","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Disposables/ScheduledDisposable.cs#L7-L43","documentation":"ScheduledDisposable's constructor requires a non-null IDisposable resource; the value is stored in a SingleAssignmentDisposable and null is rejected with ArgumentNullException. Both constructor parameters are individually validated, so this fires only when the second argument is null.","triggerScenarios":"Calling new ScheduledDisposable(scheduler, null) — passing null for the 'disposable' parameter, typically when the wrapped resource comes from a factory or optional lookup that returned null.","commonSituations":"Wrapping the result of a GetResource()/TryGetValue pattern that can return null, or a conditional resource acquisition where one branch never assigns the disposable.","solutions":["Ensure the resource to dispose is created before constructing ScheduledDisposable.","Use Disposable.Empty as a non-null placeholder when there is nothing to dispose.","Null-check the resource first and skip creating the ScheduledDisposable if absent."],"exampleFix":"// before\nvar sd = new ScheduledDisposable(scheduler, AcquireResource()); // may be null\n// after\nvar resource = AcquireResource() ?? Disposable.Empty;\nvar sd = new ScheduledDisposable(scheduler, resource);","handlingStrategy":"validation","validationCode":"if (resource is null) resource = Disposable.Empty;\nvar sd = new ScheduledDisposable(scheduler, resource);","typeGuard":"static bool HasResource(IDisposable d) => d is not null;","tryCatchPattern":"try { var sd = new ScheduledDisposable(scheduler, resource); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"disposable\") { /* substitute Disposable.Empty and retry */ }","preventionTips":["Coalesce nullable acquisition results with Disposable.Empty before wrapping.","Keep resource-acquisition methods non-null-returning (return Empty for 'nothing to do').","Test code paths where the wrapped resource may be absent."],"tags":["null-argument","disposables","system-reactive","argument-validation"],"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"}