puppetlabs/puppet · error · ArgumentError
Tries must be an integer
Error message
Tries must be an integer
What it means
The Puppet `exec` type munges its `tries` parameter: when the value is a String it must match the digit-only regex /^\d+$/ before Integer() converts it. Any string containing letters, a sign, a decimal point, a comma, or whitespace raises this ArgumentError while the resource is being built or the catalog compiled.
Source
Thrown at lib/puppet/type/exec.rb:355
rescue ArgumentError => e
raise ArgumentError, _("The timeout must be a number."), e.backtrace
end
[value, 0.0].max
end
defaultto 300
end
newparam(:tries) do
desc "The number of times execution of the command should be tried.
This many attempts will be made to execute the command until an
acceptable return code is returned. Note that the timeout parameter
applies to each try rather than to the complete set of tries."
munge do |value|
if value.is_a?(String)
unless value =~ /^\d+$/
raise ArgumentError, _("Tries must be an integer")
end
value = Integer(value)
end
raise ArgumentError, _("Tries must be an integer >= 1") if value < 1
value
end
defaultto 1
end
newparam(:try_sleep) do
desc "The time to sleep in seconds between 'tries'."
munge do |value|
if value.is_a?(String)
unless value =~ /^[-\d.]+$/View on GitHub (pinned to e227c27540)
Solutions
- Set tries to a plain Integer: `tries => 3` (or a digit-only string such as '3').
- If the value comes from Hiera or a template, normalize before use: `tries => Integer($raw)`.
- Strip whitespace from strings: `tries => regsubst($raw, '\s', '', 'G')`.
- Catch it early with `puppet parser validate` or catalog compilation in CI.
Example fix
// before
exec { 'migrate':
command => '/opt/app/migrate.sh',
tries => '3.0', // '.' fails /^\d+$/
}
// after
exec { 'migrate':
command => '/opt/app/migrate.sh',
tries => 3,
} Defensive patterns
Strategy: validation
Validate before calling
// Puppet, before declaring the exec
unless $tries =~ Integer or ($tries =~ String and $tries =~ Pattern[/\A\d+\z/]) {
fail("exec: tries must be an integer >= 1 or digit-only string, got '${tries}'")
} Type guard
def valid_exec_tries?(v) v.is_a?(Integer) ? v >= 1 : v.is_a?(String) && v.match?(/\A\d+\z/) && v.to_i >= 1 end
Try / catch
When building resources in Ruby (Puppet::Type::Exec.new), wrap creation in begin/rescue ArgumentError and re-raise with the resource title for context; in manifests the error surfaces at compile time, so catch it with `puppet parser validate` in CI rather than at runtime.
Prevention
- Always write tries as a bare integer (tries => 3).
- Normalize Hiera/template values with Integer() before passing them.
- Strip whitespace from interpolated strings (regsubst($v, '\s', '', 'G')).
- Run puppet parser validate / puppet-lint in CI to catch munge errors pre-deploy.
When it happens
Trigger: Declaring `exec { 'x': command => '...', tries => 'abc' }`; passing '1.5' or '2.0' (the '.' fails /^\d+$/); values like '-1', '+3', ' 3', '1,000', '0x10'; values interpolated from ERB/EPP templates or Hiera that arrive as "3\n". Bare Integers and digit-only strings pass.
Common situations: Hiera/YAML values stored as formatted strings; template interpolation appending newlines or spaces; attempts to express fractional retry counts; quoting habits from shell scripts carrying stray characters into the manifest.
Related errors
- Tries must be an integer >= 1
- try_sleep must be a number
- Unrecognized value for request 'merge' parameter: '%{merge}'
- Invalid 'hasstatus' value #{value.inspect}
- Expected an Array or String, got a %{klass}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/faeda9c2dffcff3d.
Report an issue: GitHub.