{"record":{"id":"c36292263f3abf48","repo":"puppetlabs/puppet","slug":"the-timeout-must-be-a-number","errorCode":null,"errorMessage":"The timeout must be a number.","messagePattern":"The timeout must be a number\\.","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/type/exec.rb","lineNumber":338,"sourceCode":"          return value.to_i(8)\n        else\n          raise Puppet::Error, _(\"The umask specification is invalid: %{value}\") % { value: value.inspect }\n        end\n      end\n    end\n\n    newparam(:timeout) do\n      desc \"The maximum time the command should take.  If the command takes\n        longer than the timeout, the command is considered to have failed\n        and will be stopped. The timeout is specified in seconds. The default\n        timeout is 300 seconds and you can set it to 0 to disable the timeout.\"\n\n      munge do |value|\n        value = value.shift if value.is_a?(Array)\n        begin\n          value = Float(value)\n        rescue ArgumentError => e\n          raise ArgumentError, _(\"The timeout must be a number.\"), e.backtrace\n        end\n        [value, 0.0].max\n      end\n\n      defaultto 300\n    end\n\n    newparam(:tries) do\n      desc \"The number of times execution of the command should be tried.\n        This many attempts will be made to execute the command until an\n        acceptable return code is returned. Note that the timeout parameter\n        applies to each try rather than to the complete set of tries.\"\n\n      munge do |value|\n        if value.is_a?(String)\n          unless value =~ /^\\d+$/\n            raise ArgumentError, _(\"Tries must be an integer\")\n          end","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/type/exec.rb#L320-L356","documentation":"The exec type's timeout parameter munges its value by first shifting out of an Array and then calling Float(value); an ArgumentError from that conversion is re-raised as ArgumentError 'The timeout must be a number.' (with the original backtrace attached). Valid inputs include integers, floats, and numeric strings like '300'; the munge clamps the result to a minimum of 0.0, and 0 disables the timeout.","triggerScenarios":"timeout => '5 minutes', timeout => 'none', timeout => '1m30s', or any non-numeric string. Values arriving from hiera as human units or from helpers returning duration strings all fail. Note nil (undef) raises TypeError, not this error, and arrays are tolerated by taking the first element.","commonSituations":"Duration syntax copied from systemd/terraform ('30s') into Puppet data; hiera values quoted with units; refactors switching an integer setting to a templated string; defaults like 'none' intended to mean no limit instead of 0.","solutions":["Use plain seconds: timeout => 300 (integer/float) or the string '300'","Set 0 to disable the timeout entirely, not 'none'","Convert human units before applying (e.g., 1.5 * 60 in Puppet code, or keep data as numbers)","Validate data files: ensure profile::exec_timeout keys are numeric (hiera data linters catch quoted numbers)"],"exampleFix":"# before\nexec { 'backup': command => '/usr/local/bin/backup', timeout => '2 hours' } # => ArgumentError\n\n# after\nexec { 'backup': command => '/usr/local/bin/backup', timeout => 7200 }","handlingStrategy":"validation","validationCode":"v = value.is_a?(Array) ? value.first : value\nFloat(v) rescue raise ArgumentError, 'timeout must be numeric seconds (0 disables)'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store timeouts as bare numbers (seconds) in data; convert units in code","Use 0 to disable the timeout, never 'none'","Validate dynamic values with Float() before assigning the parameter"],"tags":["puppet","exec","timeout","numeric-coercion","attribute-type"],"backgroundTag":"invalid-attribute-type","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}