{"record":{"id":"33080582c0d08df5","repo":"App-vNext/Polly","slug":"numberofexecutions-per-timespan-must-be-an-integer-330805","errorCode":null,"errorMessage":"numberOfExecutions per timespan must be an integer greater than or equal to 1.","messagePattern":"numberOfExecutions per timespan must be an integer greater than or equal to 1\\.","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Polly/RateLimit/AsyncRateLimitTResultSyntax.cs","lineNumber":68,"sourceCode":"    /// with a maximum burst size of <paramref name=\"maxBurst\"/>.\n    /// </summary>\n    /// <typeparam name=\"TResult\">The type of return values this policy will handle.</typeparam>\n    /// <param name=\"numberOfExecutions\">The number of executions (call it N) permitted per timespan.</param>\n    /// <param name=\"perTimeSpan\">How often N executions are permitted.</param>\n    /// <param name=\"maxBurst\">The maximum number of executions that will be permitted in a single burst (for example if none have been executed for a while).\n    /// This equates to the bucket-capacity of a token-bucket implementation.</param>\n    /// <param name=\"retryAfterFactory\">An (optional) factory to use to express retry-after back to the caller, when an operation is rate-limited.\n    /// <remarks>If null, a <see cref=\"RateLimitRejectedException\"/> with property <see cref=\"RateLimitRejectedException.RetryAfter\"/> will be thrown to indicate rate-limiting.</remarks></param>\n    /// <returns>The policy instance.</returns>\n    public static AsyncRateLimitPolicy<TResult> RateLimitAsync<TResult>(\n        int numberOfExecutions,\n        TimeSpan perTimeSpan,\n        int maxBurst,\n        Func<TimeSpan, Context, TResult>? retryAfterFactory)\n    {\n        if (numberOfExecutions < 1)\n        {\n            throw new ArgumentOutOfRangeException(nameof(numberOfExecutions), numberOfExecutions, $\"{nameof(numberOfExecutions)} per timespan must be an integer greater than or equal to 1.\");\n        }\n\n        if (perTimeSpan <= TimeSpan.Zero)\n        {\n            throw new ArgumentOutOfRangeException(nameof(perTimeSpan), perTimeSpan, $\"{nameof(perTimeSpan)} must be a positive timespan.\");\n        }\n\n        if (maxBurst < 1)\n        {\n            throw new ArgumentOutOfRangeException(nameof(maxBurst), maxBurst, $\"{nameof(maxBurst)} must be an integer greater than or equal to 1.\");\n        }\n\n        var onePer = TimeSpan.FromTicks(perTimeSpan.Ticks / numberOfExecutions);\n\n        if (onePer <= TimeSpan.Zero)\n        {\n            throw new ArgumentOutOfRangeException(nameof(perTimeSpan), perTimeSpan, \"The number of executions per timespan must be positive.\");\n        }","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/App-vNext/Polly/blob/d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac/src/Polly/RateLimit/AsyncRateLimitTResultSyntax.cs#L50-L86","documentation":"Thrown by the typed RateLimitAsync<TResult>(int, TimeSpan, int, Func<TimeSpan,Context,TResult>?) overload when numberOfExecutions is less than 1. Identical validation to the factory-less overload; the typed (TResult-locked) policy applies the same lower bound on executions per window.","triggerScenarios":"Calling Policy.RateLimitAsync<TResult>(0, ts, burst, factory) or with a negative numberOfExecutions. The factory argument does not affect this guard.","commonSituations":"Config-driven numberOfExecutions that parses to 0 (missing key), a feature flag setting the limit to 0 to 'disable', or mis-scaled units from configuration.","solutions":["Set numberOfExecutions to a positive integer matching measured load.","Clamp config: Math.Max(1, parsed); reject non-positive values at the config layer.","To disable rate limiting, skip policy construction rather than passing 0.","Add a config validation step at startup that asserts all three numeric bounds."],"exampleFix":"// before\nvar p = Policy.RateLimitAsync<int>(0, TimeSpan.FromSeconds(1), 10, null);\n\n// after\nvar p = Policy.RateLimitAsync<int>(10, TimeSpan.FromSeconds(1), 10, null);","handlingStrategy":"validation","validationCode":"int n = Math.Max(1, parsedNumberOfExecutions);\nvar p = Policy.RateLimitAsync<TResult>(n, perTimeSpan, maxBurst, retryAfterFactory);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate all three numeric bounds at startup.","Clamp config-derived numberOfExecutions with Math.Max(1, value).","Use 'skip policy construction' to disable limiting, never 0."],"tags":["argumentoutofrange","ratelimit","config","validation","tresult","legacy-api"],"backgroundTag":null,"analyzedSha":"d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac","analyzedAt":"2026-08-13T16:36:01.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}