puppetlabs/puppet · error · CommandlineError

option '%{arg}' needs an integer

Error message

option '%{arg}' needs an integer

What it means

Options typed :int or :ints run each parameter through parse_integer_parameter, which accepts only strings matching /^\d+$/ (trollop.rb:659) — bare digits with no sign, separator, or unit. Anything else, including '-1', '+5', '1.5', '0x10', '1e3', or '1_000', raises CommandlineError "option '--x' needs an integer".

Source

Thrown at lib/puppet/util/command_line/trollop.rb:659

              yield "-#{a}", nil
            end
          end
        else
          if @stop_on_unknown
            remains += args[i..]
            return remains
          else
            remains << args[i]
            i += 1
          end
        end
      end

      remains
    end

    def parse_integer_parameter param, arg
      raise CommandlineError, _("option '%{arg}' needs an integer") % { arg: arg } unless param =~ /^\d+$/

      param.to_i
    end

    def parse_float_parameter param, arg
      raise CommandlineError, _("option '%{arg}' needs a floating-point number") % { arg: arg } unless param =~ FLOAT_RE

      param.to_f
    end

    def parse_io_parameter param, arg
      case param
      when /^(stdin|-)$/i; $stdin
      else
        require 'open-uri'
        begin
          URI.parse(param).open
        rescue SystemCallError => e

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass a plain non-negative integer: `--count 5`
  2. Declare the option `type: :float` if decimal values are legitimate
  3. Accept a string option and convert with Integer(value) or Integer(value, 0) in a :callback when negatives or hex are required

Example fix

# before
opt :count, 'Number of retries', type: :int
$ mytool --count -1   # '-1' fails /^\d+$/

# after
$ mytool --count 5
# or, if negatives must be supported:
opt :count, 'Number of retries', type: :string do |v| Integer(v); end
Defensive patterns

Strategy: validation

Validate before calling

# Trollop only accepts /^\d+$/ for :int options - check before invoking
value = argv[i + 1]
abort "#{value.inspect} is not a valid non-negative integer" unless value =~ /^\d+$/

Type guard

# Ruby value guard mirroring the parser's rule
def trollop_integer?(s)
  s.is_a?(String) && s =~ /^\d+$/
end
# If you need signed/hex integers, do NOT use type: :int - see the fallback below

Try / catch

begin
  opts = parser.parse(argv)
rescue Puppet::Util::CommandLine::Trollop::CommandlineError => e
  raise unless e.message.include?('needs an integer')
  name = e.message[/option '(.+)' needs/, 1]
  abort "#{name} accepts only plain digits (no sign, hex, or decimals)"
end

Prevention

When it happens

Trigger: `--count abc`; `--count 1.5`; `--count 0x1F`; `--count -1` (when the value survives token classification); whitespace-padded values from generated command lines.

Common situations: Passing negative numbers to integer options; hex or thousands-separated numbers produced by scripts; decimal values where the option was declared :int.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/0217a1db4d2a94b5. Report an issue: GitHub.