{"record":{"id":"b80b8154000adaab","repo":"puppetlabs/puppet","slug":"value-is-not-a-positive-integer-the-timeout","errorCode":null,"errorMessage":"\"%{value}\" is not a positive integer: the timeout parameter must be specified as a positive integer","messagePattern":"\"%(.+?)\" is not a positive integer: the timeout parameter must be specified as a positive integer","errorType":"validation","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/type/service.rb","lineNumber":285,"sourceCode":"        the init script's `stop` and `start` commands will be used.\"\n      newvalues(:true, :false)\n    end\n\n    newparam(:manifest) do\n      desc \"Specify a command to config a service, or a path to a manifest to do so.\"\n    end\n\n    newparam(:timeout, :required_features => :configurable_timeout) do\n      desc \"Specify an optional minimum timeout (in seconds) for puppet to wait when syncing service properties\"\n      defaultto { provider.respond_to?(:default_timeout) ? provider.default_timeout : 10 }\n\n      munge do |value|\n        value = value.to_i\n        raise if value < 1\n\n        value\n      rescue\n        raise Puppet::Error, _(\"\\\"%{value}\\\" is not a positive integer: the timeout parameter must be specified as a positive integer\") % { value: value }\n      end\n    end\n\n    # Basically just a synonym for restarting.  Used to respond\n    # to events.\n    def refresh\n      # Only restart if we're actually running\n      if (@parameters[:ensure] || newattr(:ensure)).retrieve == :running\n        provider.restart\n      else\n        debug \"Skipping restart; service is not running\"\n      end\n    end\n\n    def self.needs_ensure_retrieved\n      false\n    end\n","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/type/service.rb#L267-L303","documentation":"The service `timeout` parameter (seconds Puppet waits when syncing service properties, for providers with configurable_timeout) munges the value with to_i and requires the result to be >= 1, else Puppet::Error (lib/puppet/type/service.rb:285). Because of the to_i cast, non-numeric strings like 'soon' become 0 and also surface as \"not a positive integer\".","triggerScenarios":"`service { 'svc': timeout => 0 }`; `timeout => -1`; `timeout => 'soon'` ('soon'.to_i == 0); data-driven values computed as 0.","commonSituations":"Hiera defaults of 0 meaning 'no wait'; numeric strings from ENC/external data; arithmetic producing 0 or negatives.","solutions":["Set a positive integer (e.g. timeout => 60)","Fix the upstream data (Hiera/ENC) that supplies 0 or non-numeric values","Validate/cast in the wrapper: fail fast on timeout < 1"],"exampleFix":"# before\nservice { 'mysvc':\n  ensure  => running,\n  timeout => 0,\n}\n\n# after\nservice { 'mysvc':\n  ensure  => running,\n  timeout => 60,\n}","handlingStrategy":"validation","validationCode":"if $timeout != undef and !($timeout =~ /\\A\\d+\\z/ and Integer($timeout) >= 1) {\n  fail('service timeout must be a positive integer')\n}","typeGuard":"def valid_timeout?(v)\n  n = v.to_i\n  v.is_a?(Integer) ? v >= 1 : (v.is_a?(String) && v =~ /\\A\\d+\\z/ && n >= 1)\nend","tryCatchPattern":"begin\n  Puppet::Type.type(:service).new(name: 'mysvc', timeout: 0)\nrescue Puppet::Error => e\n  raise unless e.message.include?('positive integer')\n  # clamp to a sane minimum (e.g. 10) and rebuild\nend","preventionTips":["Type timeout as Integer[1, default] in profile signatures","Audit Hiera for zero/negative timeout values","Remember to_i means garbage strings fail as 'not positive', not as words"],"tags":["puppet","service","timeout","invalid-value"],"backgroundTag":"positive-integer-required","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}