{"record":{"id":"b224dde9eab3d37e","repo":"dotnet/reactive","slug":"argumentoutofrangeexception-nameof-maxconcurrent","errorCode":null,"errorMessage":"ArgumentOutOfRangeException(nameof(maxConcurrent))","messagePattern":"ArgumentOutOfRangeException\\(nameof\\(maxConcurrent\\)\\)","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs","lineNumber":494,"sourceCode":"        /// <summary>\n        /// Merges elements from all inner observable sequences into a single observable sequence, limiting the number of concurrent subscriptions to inner sequences.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequences.</typeparam>\n        /// <param name=\"sources\">Observable sequence of inner observable sequences.</param>\n        /// <param name=\"maxConcurrent\">Maximum number of inner observable sequences being subscribed to concurrently.</param>\n        /// <returns>The observable sequence that merges the elements of the inner sequences.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"sources\"/> is null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"maxConcurrent\"/> is less than or equal to zero.</exception>\n        public static IObservable<TSource> Merge<TSource>(this IObservable<IObservable<TSource>> sources, int maxConcurrent)\n        {\n            if (sources == null)\n            {\n                throw new ArgumentNullException(nameof(sources));\n            }\n\n            if (maxConcurrent <= 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(maxConcurrent));\n            }\n\n            return s_impl.Merge(sources, maxConcurrent);\n        }\n\n        /// <summary>\n        /// Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence, limiting the number of concurrent subscriptions to inner sequences.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequences.</typeparam>\n        /// <param name=\"sources\">Enumerable sequence of observable sequences.</param>\n        /// <param name=\"maxConcurrent\">Maximum number of observable sequences being subscribed to concurrently.</param>\n        /// <returns>The observable sequence that merges the elements of the observable sequences.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"sources\"/> is null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"maxConcurrent\"/> is less than or equal to zero.</exception>\n        public static IObservable<TSource> Merge<TSource>(this IEnumerable<IObservable<TSource>> sources, int maxConcurrent)\n        {\n            if (sources == null)\n            {","sourceCodeStart":476,"sourceCodeEnd":512,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs#L476-L512","documentation":"Observable.Merge(sources, maxConcurrent) throws ArgumentOutOfRangeException when maxConcurrent is less than or equal to zero. Concurrency limits of 0 or negative values are meaningless (at least one inner stream must be allowed), so the library rejects them eagerly after the null check on sources.","triggerScenarios":"Calling sources.Merge(0) or sources.Merge(-1); passing a computed limit from config (e.g. 'maxConcurrentConnections': 0) or an uninitialized int defaulting to 0.","commonSituations":"Config files where 0 was intended to mean 'unlimited' but the API expects a positive integer; parsing an empty/invalid setting into default(int) = 0; off-by-one in a derived limit.","solutions":["Pass a positive maxConcurrent value (>= 1), e.g. Math.Max(1, configuredLimit).","If 0 means 'no limit', call the parameterless Merge() overload instead.","Validate the config value at load time and fail with a clear message before building the pipeline."],"exampleFix":"// before\nvar merged = streams.Merge(maxConcurrentFromConfig); // may be 0\n\n// after\nvar merged = maxConcurrentFromConfig > 0\n    ? streams.Merge(maxConcurrentFromConfig)\n    : streams.Merge(); // treat 0 as unlimited","handlingStrategy":"validation","validationCode":"if (maxConcurrent <= 0)\n    throw new ArgumentOutOfRangeException(nameof(maxConcurrent), \"Must be greater than zero\");\nvar merged = sources.Merge(maxConcurrent);","typeGuard":"bool IsValidConcurrency(int max) => max > 0;","tryCatchPattern":"try { var merged = sources.Merge(maxConcurrent); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"maxConcurrent\") { log.Error(\"maxConcurrent must be > 0, got {0}\", maxConcurrent); throw; }","preventionTips":["Clamp configured limits with Math.Max(1, value).","Do not use 0 to mean 'unlimited'; call the parameterless Merge overload instead.","Validate config integers at load time, before pipeline construction."],"tags":["csharp","reactive-extensions","argument-range","concurrency"],"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"}