{"record":{"id":"c965dd1e87be9a2c","repo":"ruby-concurrency/concurrent-ruby","slug":"must-be-greater-than-zero","errorCode":null,"errorMessage":"must be greater than zero","messagePattern":"must be greater than zero","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/concurrent-ruby/concurrent/timer_task.rb","lineNumber":270,"sourceCode":"    #   task = Concurrent::TimerTask.execute(execution_interval: 10){ print \"Hello World\\n\" }\n    #   task.running? #=> true\n    def self.execute(opts = {}, &task)\n      TimerTask.new(opts, &task).execute\n    end\n\n    # @!attribute [rw] execution_interval\n    # @return [Fixnum] Number of seconds after the task completes before the\n    #   task is performed again.\n    def execution_interval\n      synchronize { @execution_interval }\n    end\n\n    # @!attribute [rw] execution_interval\n    # @return [Fixnum] Number of seconds after the task completes before the\n    #   task is performed again.\n    def execution_interval=(value)\n      if (value = value.to_f) <= 0.0\n        raise ArgumentError.new('must be greater than zero')\n      else\n        synchronize { @execution_interval = value }\n      end\n    end\n\n    # @!attribute [r] interval_type\n    # @return [Symbol] method to calculate the interval between executions\n    attr_reader :interval_type\n\n    # @!attribute [rw] timeout_interval\n    # @return [Fixnum] Number of seconds the task can run before it is\n    #   considered to have failed.\n    def timeout_interval\n      warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly'\n    end\n\n    # @!attribute [rw] timeout_interval\n    # @return [Fixnum] Number of seconds the task can run before it is","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/ruby-concurrency/concurrent-ruby/blob/0b88d5ff75f69b3740c8f0868e76f833cb2fd45d/lib/concurrent-ruby/concurrent/timer_task.rb#L252-L288","documentation":"TimerTask#execution_interval= rejects values that are <= 0 after to_f (unlike ScheduledTask, zero is not allowed here), raising ArgumentError('must be greater than zero'). The same setter runs during TimerTask.new via the :execution / :execution_interval option, so bad intervals surface at construction. Note nil.to_f == 0.0, so a missing config value raises this error. The companion timeout_interval= is deprecated and only warns.","triggerScenarios":"TimerTask.new(execution_interval: 0) or execution_interval: -5; timer_task.execution_interval = 0; interval sourced from config/ENV that is nil, absent, or the string '0' ('0'.to_f == 0.0).","commonSituations":"Intervals read from YAML/ENV where 'disable the timer' was encoded as 0 or left blank; ops-configured intervals with typos or negative numbers; dividing to produce a Float that lands on 0.0.","solutions":["Default the value at the boundary: interval = Float(cfg.fetch('interval', 30))","Treat 0/nil as 'do not start the timer' instead of passing it through: skip TimerTask.new unless interval && interval > 0","Validate once at config load: raise unless interval.is_a?(Numeric) && interval > 0"],"exampleFix":"# before (nil from missing config becomes 0.0 and raises)\ntask = Concurrent::TimerTask.new(execution_interval: cfg['interval']) { sync }\n\n# after (explicit default + explicit disable semantics)\ninterval = Float(cfg.fetch('interval', 30))\ntask = interval > 0 ? Concurrent::TimerTask.new(execution_interval: interval) { sync } : nil","handlingStrategy":"validation","validationCode":"interval = Float(interval)\nraise ArgumentError, \"interval #{interval} must be > 0\" unless interval > 0\nConcurrent::TimerTask.new(execution_interval: interval) { work }","typeGuard":"def valid_interval?(v)\n  v.is_a?(Numeric) && v.to_f > 0\nend","tryCatchPattern":"begin\n  timer.execution_interval = new_interval\nrescue ArgumentError\n  logger.warn(\"ignoring invalid interval #{new_interval.inspect}\")\nend","preventionTips":["Coerce and default intervals at the config boundary (Float(cfg.fetch('interval', DEFAULT)))","Treat 0/nil as 'timer disabled' rather than passing it to TimerTask","Remember nil.to_f == 0.0 — a missing key raises this exact error"],"tags":["ruby","concurrency","timer-task","argument-error","interval-validation"],"backgroundTag":"invalid-time-interval","analyzedSha":"0b88d5ff75f69b3740c8f0868e76f833cb2fd45d","analyzedAt":"2026-08-21T20:12:56.291Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}