{"record":{"id":"6b966230faab7b2b","repo":"gofr-dev/gofr","slug":"burst-must-be-positive","errorCode":null,"errorMessage":"burst must be positive","messagePattern":"burst must be positive","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/http/middleware/rate_limiter.go","lineNumber":20,"sourceCode":"\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\n\tgofrHttp \"gofr.dev/pkg/gofr/http\"\n)\n\nvar (\n\t// errInvalidRequestsPerSecond is returned when RequestsPerSecond is not positive.\n\terrInvalidRequestsPerSecond = errors.New(\"requestsPerSecond must be positive\")\n\n\t// errInvalidBurst is returned when Burst is not positive.\n\terrInvalidBurst = errors.New(\"burst must be positive\")\n)\n\n// RateLimiterConfig holds configuration for rate limiting.\n//\n// Note: The default implementation uses in-memory token buckets and is suitable\n// for single-pod deployments. In multi-pod deployments, each pod will enforce\n// limits independently. For distributed rate limiting across multiple pods,\n// a Redis-backed store can be implemented in a future update.\n//\n// Security: When using PerIP=true, only enable TrustedProxies if your application\n// is behind a trusted reverse proxy (nginx, ALB, etc.) that sets X-Forwarded-For.\n// Without trusted proxies, clients can spoof IP addresses to bypass rate limits.\n//\n// Cleanup: The rate limiter starts a background goroutine that runs for the\n// application lifetime. This is acceptable for long-running servers but consider\n// calling Store.StopCleanup() in shutdown handlers if needed.\ntype RateLimiterConfig struct {\n\tRequestsPerSecond float64","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/http/middleware/rate_limiter.go#L2-L38","documentation":"errInvalidBurst is returned by RateLimiterConfig.Validate when Burst is zero or negative. The burst size caps how many requests can pass at once via the token bucket; a non-positive burst makes the limiter useless, so it is rejected.","triggerScenarios":"Constructing a RateLimiterConfig without setting Burst, or explicitly setting Burst to 0/negative while RequestsPerSecond is valid.","commonSituations":"Setting only RequestsPerSecond and assuming Burst is optional; deriving Burst from a config value that defaults to 0; misunderstanding that Burst must also be positive.","solutions":["Set Burst to a positive integer (commonly a multiple of RequestsPerSecond, e.g. 2x)","Validate all rate limiter fields in your config-loading layer before constructing the middleware","Use the Validate() method proactively on user-supplied configs and surface a clear message"],"exampleFix":"// before\nmiddleware.RateLimiterConfig{RequestsPerSecond: 10}\n// after\nmiddleware.RateLimiterConfig{RequestsPerSecond: 10, Burst: 20}","handlingStrategy":"validation","validationCode":"if cfg.Burst <= 0 { return fmt.Errorf(\"Burst must be > 0, got %v\", cfg.Burst) }","typeGuard":"func validRateConfig(c RateLimiterConfig) bool { return c.RequestsPerSecond > 0 && c.Burst > 0 }","tryCatchPattern":null,"preventionTips":["Set Burst explicitly whenever you set RequestsPerSecond","Treat Burst as a required field in code review checklists","Default Burst to ~2x RequestsPerSecond when unset"],"tags":["rate-limiting","configuration","middleware"],"backgroundTag":"invalid-rate-limiter-config","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}