{"record":{"id":"476daa48262b87c9","repo":"harness/harness","slug":"provided-concurrency-d-is-invalid-has-to-be-bet","errorCode":null,"errorMessage":"provided concurrency %d is invalid - has to be between 1 and %d","messagePattern":"provided concurrency (.+?) is invalid - has to be between 1 and (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"stream/options.go","lineNumber":50,"sourceCode":"\n// ConsumerOption is used to configure consumers.\ntype ConsumerOption interface {\n\tapply(*ConsumerConfig)\n}\n\n// consumerOptionFunc allows to have functions implement the ConsumerOption interface.\ntype consumerOptionFunc func(*ConsumerConfig)\n\n// Apply calls f(config).\nfunc (f consumerOptionFunc) apply(config *ConsumerConfig) {\n\tf(config)\n}\n\n// WithConcurrency sets up the concurrency of the stream consumer.\nfunc WithConcurrency(concurrency int) ConsumerOption {\n\tif concurrency < 1 || concurrency > MaxConcurrency {\n\t\t// misconfiguration - panic to keep options clean\n\t\tpanic(fmt.Sprintf(\"provided concurrency %d is invalid - has to be between 1 and %d\",\n\t\t\tconcurrency, MaxConcurrency))\n\t}\n\treturn consumerOptionFunc(func(c *ConsumerConfig) {\n\t\tc.Concurrency = concurrency\n\t})\n}\n\n// WithHandlerOptions sets up the default handler options of a stream consumer.\nfunc WithHandlerOptions(opts ...HandlerOption) ConsumerOption {\n\treturn consumerOptionFunc(func(c *ConsumerConfig) {\n\t\tfor _, opt := range opts {\n\t\t\topt.apply(&c.DefaultHandlerConfig)\n\t\t}\n\t})\n}\n\n// HandlerOption is used to configure the handler consuming a single stream.\ntype HandlerOption interface {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/harness/harness/blob/828c7abf3a3cef8b5d3c5924ddd53223070a2aca/stream/options.go#L32-L68","documentation":"Go library (stream package) panics from the WithConcurrency consumer option when the supplied concurrency is outside [1, MaxConcurrency] (MaxConcurrency = 64). The package deliberately panics instead of returning an error to keep the functional-options API clean — an invalid concurrency is treated as a programmer misconfiguration that should crash loudly at startup rather than silently degrade.","triggerScenarios":"Calling stream.WithConcurrency(n) with n < 1 (including 0, e.g. an uninitialised int or a computed value that underflowed) or n > 64 (e.g. pulled from an env var or config file without clamping). The panic occurs at Consumer construction time, before any messages flow.","commonSituations":"Reading concurrency from a config map with a missing key defaulting to 0; deriving concurrency from runtime.NumCPU() multiplied by a factor exceeding 64; passing a user-supplied CLI flag straight through; copying example code that assumed a higher cap after a library version with different limits.","solutions":["Clamp the value before passing it: concurrency = min(max(concurrency, 1), stream.MaxConcurrency).","If the value comes from config/env, validate and fail with a clear configuration error message before constructing the consumer.","Raise the value only if you truly need >64 concurrent handlers; otherwise scale consumers horizontally rather than raising concurrency.","Check the option against the exported stream.MaxConcurrency constant (64) instead of hardcoding the number, so upgrades stay correct."],"exampleFix":"// before\nconsumer := stream.NewConsumer(name, handler,\n  stream.WithConcurrency(cfg.Concurrency), // panics if 0 or >64\n)\n\n// after\nconcurrency := cfg.Concurrency\nif concurrency < 1 || concurrency > stream.MaxConcurrency {\n  return fmt.Errorf(\"invalid concurrency %d: must be 1..%d\", concurrency, stream.MaxConcurrency)\n}\nconsumer := stream.NewConsumer(name, handler,\n  stream.WithConcurrency(concurrency),\n)","handlingStrategy":"validation","validationCode":"// validate before constructing the consumer\nfunc validConcurrency(n int) bool { return n >= 1 && n <= stream.MaxConcurrency }\n\nif !validConcurrency(cfg.Concurrency) {\n  return fmt.Errorf(\"concurrency %d out of range [1,%d]\", cfg.Concurrency, stream.MaxConcurrency)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass unclamped config/env values into WithConcurrency; validate at load time.","Reference stream.MaxConcurrency instead of hardcoding 64.","Treat a panic in this option as a config bug — add a startup smoke test that constructs the consumer."],"tags":["go","redis-streams","consumer-config","panic","functional-options","validation"],"backgroundTag":null,"analyzedSha":"828c7abf3a3cef8b5d3c5924ddd53223070a2aca","analyzedAt":"2026-08-15T13:04:16.739Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}