{"record":{"id":"4ab2b72a1859973d","repo":"dotnet/reactive","slug":"argumentoutofrangeexception-buffersize","errorCode":null,"errorMessage":"ArgumentOutOfRangeException: bufferSize","messagePattern":"ArgumentOutOfRangeException: bufferSize","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs","lineNumber":668,"sourceCode":"        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence whose elements will be multicasted through a single shared subscription.</param>\n        /// <param name=\"bufferSize\">Maximum element count of the replay buffer.</param>\n        /// <param name=\"scheduler\">Scheduler where connected observers will be invoked on.</param>\n        /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"scheduler\"/> is null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"bufferSize\"/> is less than zero.</exception>\n        /// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>\n        /// <seealso cref=\"ReplaySubject{T}\"/>\n        public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize, IScheduler scheduler)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (bufferSize < 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(bufferSize));\n            }\n\n            if (scheduler == null)\n            {\n                throw new ArgumentNullException(nameof(scheduler));\n            }\n\n            return s_impl.Replay(source, bufferSize, scheduler);\n        }\n\n        /// <summary>\n        /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum element count for the replay buffer.\n        /// This operator is a specialization of Multicast using a <see cref=\"ReplaySubject{T}\"/>.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence.</typeparam>\n        /// <param name=\"source\">Source sequence whose elements will be multicasted through a single shared subscription.</param>\n        /// <param name=\"selector\">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>","sourceCodeStart":650,"sourceCodeEnd":686,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs#L650-L686","documentation":"Replay(source, bufferSize, scheduler) requires bufferSize >= 0 because it sizes the replay buffer of a ReplaySubject; a negative count is meaningless. A negative value raises ArgumentOutOfRangeException named 'bufferSize' before any subscription happens.","triggerScenarios":"Calling source.Replay(bufferSize, scheduler) with a negative bufferSize, e.g. computed from a subtraction (count - dropped) or an unvalidated user/setting value.","commonSituations":"Config files or app settings where the buffer size was edited to a negative number; arithmetic like take(5) minus received(7); parsing user input without range validation.","solutions":["Clamp the buffer size: Math.Max(0, requestedSize).","Validate settings at startup and fail fast with a clear message if negative.","If unlimited replay is desired, use the parameterless Replay(source) overload instead of a huge/negative size."],"exampleFix":"// before\nint size = configuredMax - consumed; // can go negative\nvar replay = source.Replay(size, Scheduler.Default);\n// after\nint size = Math.Max(0, configuredMax - consumed);\nvar replay = source.Replay(size, Scheduler.Default);","handlingStrategy":"validation","validationCode":"if (bufferSize < 0)\n    throw new ArgumentOutOfRangeException(nameof(bufferSize), bufferSize, \"Replay buffer size must be >= 0.\");\nvar replay = source.Replay(bufferSize, scheduler);","typeGuard":"static int PositiveOrZero(int n) => Math.Max(0, n);","tryCatchPattern":"try { var replay = source.Replay(size, Scheduler.Default); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"bufferSize\")\n{\n    var replay = source.Replay(0, Scheduler.Default); // or log and abort\n}","preventionTips":["Clamp computed sizes with Math.Max(0, n).","Validate buffer-size settings at config load time.","Sanitize user/query input that feeds numeric buffer arguments."],"tags":["argument-out-of-range","rx","replay","buffer-size"],"backgroundTag":"argument-out-of-range","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}