{"record":{"id":"51340518918db677","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-cts","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'cts')","messagePattern":"Value cannot be null\\. \\(Parameter 'cts'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Disposables/CancellationAsyncDisposable.cs","lineNumber":21,"sourceCode":"// See the LICENSE file in the project root for more information. \n\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Disposables\n{\n    public sealed class CancellationAsyncDisposable : IAsyncDisposable\n    {\n        private readonly CancellationTokenSource _cts;\n\n        public CancellationAsyncDisposable()\n            : this(new CancellationTokenSource())\n        {\n        }\n\n        public CancellationAsyncDisposable(CancellationTokenSource cts)\n        {\n            _cts = cts ?? throw new ArgumentNullException(nameof(cts));\n        }\n\n        public CancellationToken Token => _cts.Token;\n\n        public ValueTask DisposeAsync()\n        {\n            _cts.Cancel();\n\n            return default;\n        }\n    }\n}\n","sourceCodeStart":3,"sourceCodeEnd":34,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Disposables/CancellationAsyncDisposable.cs#L3-L34","documentation":"CancellationAsyncDisposable wraps a CancellationTokenSource so disposal cancels it. The constructor validates its 'cts' argument and throws ArgumentNullException when a null CancellationTokenSource is supplied, because the Token property and DisposeAsync would otherwise throw NullReferenceException later.","triggerScenarios":"new CancellationAsyncDisposable((CancellationTokenSource)null), or passing a cts field/property that was never initialized or was set to null.","commonSituations":"Storing a CTS in a field initialized lazily; receiving a null token source from another component; passing null when intending to use the parameterless constructor.","solutions":["Pass a valid, constructed CancellationTokenSource to the constructor","Use the parameterless CancellationAsyncDisposable() overload, which creates its own CTS","Null-check the cts before constructing"],"exampleFix":"// before\nvar d = new CancellationAsyncDisposable(_cts); // _cts is null here\n// after\n_cts ??= new CancellationTokenSource();\nvar d = new CancellationAsyncDisposable(_cts);","handlingStrategy":"validation","validationCode":"if (cts == null) cts = new CancellationTokenSource();","typeGuard":"bool IsValidCts(CancellationTokenSource? cts) => cts is not null;","tryCatchPattern":"try { var d = new CancellationAsyncDisposable(cts); } catch (ArgumentNullException ex) when (ex.ParamName == \"cts\") { d = new CancellationAsyncDisposable(); }","preventionTips":["Prefer the parameterless constructor when you don't already own a CTS","Initialize CTS fields inline (new CancellationTokenSource()) rather than lazily","Run cancellation-related code under nullable reference type analysis"],"tags":["argument-null","cancellation"],"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"}