{"record":{"id":"f948af7fc88b6c7a","repo":"ruby-concurrency/concurrent-ruby","slug":"number-of-threads-must-be-greater-than-zero","errorCode":null,"errorMessage":"number of threads must be greater than zero","messagePattern":"number of threads must be greater than zero","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb","lineNumber":214,"sourceCode":"  #   The API and behavior of this class are based on Java's `FixedThreadPool`\n  #\n  # @!macro thread_pool_options\n  class FixedThreadPool < ThreadPoolExecutor\n\n    # @!macro fixed_thread_pool_method_initialize\n    #\n    #   Create a new thread pool.\n    #\n    #   @param [Integer] num_threads the number of threads to allocate\n    #   @param [Hash] opts the options defining pool behavior.\n    #   @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy\n    #\n    #   @raise [ArgumentError] if `num_threads` is less than or equal to zero\n    #   @raise [ArgumentError] if `fallback_policy` is not a known policy\n    #\n    #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-\n    def initialize(num_threads, opts = {})\n      raise ArgumentError.new('number of threads must be greater than zero') if num_threads.to_i < 1\n      defaults  = { max_queue:   DEFAULT_MAX_QUEUE_SIZE,\n                    idletime:    DEFAULT_THREAD_IDLETIMEOUT }\n      overrides = { min_threads: num_threads,\n                    max_threads: num_threads }\n      super(defaults.merge(opts).merge(overrides))\n    end\n  end\nend\n","sourceCodeStart":196,"sourceCodeEnd":223,"githubUrl":"https://github.com/ruby-concurrency/concurrent-ruby/blob/0b88d5ff75f69b3740c8f0868e76f833cb2fd45d/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb#L196-L223","documentation":"Concurrent::FixedThreadPool.new(num_threads) pins min_threads = max_threads = num_threads. It raises ArgumentError when num_threads.to_i < 1. Because the value is coerced with to_i, nil (nil.to_i == 0), non-numeric strings ('abc'.to_i == 0), 0, and negatives all fail the check.","triggerScenarios":"Concurrent::FixedThreadPool.new(0) or .new(-3); .new(nil); .new(ENV['POOL_SIZE']) where the variable is unset or non-numeric; sizing arithmetic that yields zero (count * 0).","commonSituations":"Pool size read from ENV or YAML that is missing in the deployed environment; 0 used to mean 'disabled'; string sizes from CLI flags ('4' works, '' or 'four' raises); arithmetic on unknown core counts producing zero or negative values.","solutions":["Strictly convert and validate before constructing: size = Integer(ENV.fetch('POOL_SIZE', 5)); raise ArgumentError if size < 1","Default missing config to a sane positive value instead of nil or 0","Treat a 'disabled' intent as not creating the pool at all rather than passing 0","Use Integer() (raises on junk) instead of relying on to_i coercion"],"exampleFix":"# before\npool = Concurrent::FixedThreadPool.new(ENV['POOL_SIZE'])\n# after\nsize = Integer(ENV.fetch('POOL_SIZE', 5))\nraise ArgumentError, \"POOL_SIZE must be >= 1, got #{size}\" if size < 1\npool = Concurrent::FixedThreadPool.new(size)","handlingStrategy":"validation","validationCode":"size = Integer(env_value.nil? || env_value.empty? ? 5 : env_value)\nraise ArgumentError, \"pool size must be >= 1, got #{size}\" if size < 1\npool = Concurrent::FixedThreadPool.new(size)","typeGuard":"def valid_fixed_pool_size?(v)\n  v.is_a?(Numeric) && v.to_i >= 1\nend","tryCatchPattern":"begin\n  Concurrent::FixedThreadPool.new(size)\nrescue ArgumentError => e\n  raise unless e.message == 'number of threads must be greater than zero'\n  Concurrent::FixedThreadPool.new(DEFAULT_POOL_SIZE)\nend","preventionTips":["Use Integer() with fallback for ENV/config parsing instead of raw to_i","Never pass 0 or nil to mean 'disabled': skip pool creation instead","Unit-test pool sizing with unset, empty, and non-numeric config values"],"tags":["ruby","concurrency","thread-pool","executor","argument-error","configuration"],"backgroundTag":"invalid-thread-pool-configuration","analyzedSha":"0b88d5ff75f69b3740c8f0868e76f833cb2fd45d","analyzedAt":"2026-08-21T20:12:56.291Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}