{"record":{"id":"0217a1db4d2a94b5","repo":"puppetlabs/puppet","slug":"option-arg-needs-an-integer","errorCode":null,"errorMessage":"option '%{arg}' needs an integer","messagePattern":"option '%(.+?)' needs an integer","errorType":"exception","errorClass":"CommandlineError","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/command_line/trollop.rb","lineNumber":659,"sourceCode":"              yield \"-#{a}\", nil\n            end\n          end\n        else\n          if @stop_on_unknown\n            remains += args[i..]\n            return remains\n          else\n            remains << args[i]\n            i += 1\n          end\n        end\n      end\n\n      remains\n    end\n\n    def parse_integer_parameter param, arg\n      raise CommandlineError, _(\"option '%{arg}' needs an integer\") % { arg: arg } unless param =~ /^\\d+$/\n\n      param.to_i\n    end\n\n    def parse_float_parameter param, arg\n      raise CommandlineError, _(\"option '%{arg}' needs a floating-point number\") % { arg: arg } unless param =~ FLOAT_RE\n\n      param.to_f\n    end\n\n    def parse_io_parameter param, arg\n      case param\n      when /^(stdin|-)$/i; $stdin\n      else\n        require 'open-uri'\n        begin\n          URI.parse(param).open\n        rescue SystemCallError => e","sourceCodeStart":641,"sourceCodeEnd":677,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/command_line/trollop.rb#L641-L677","documentation":"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\".","triggerScenarios":"`--count abc`; `--count 1.5`; `--count 0x1F`; `--count -1` (when the value survives token classification); whitespace-padded values from generated command lines.","commonSituations":"Passing negative numbers to integer options; hex or thousands-separated numbers produced by scripts; decimal values where the option was declared :int.","solutions":["Pass a plain non-negative integer: `--count 5`","Declare the option `type: :float` if decimal values are legitimate","Accept a string option and convert with Integer(value) or Integer(value, 0) in a :callback when negatives or hex are required"],"exampleFix":"# before\nopt :count, 'Number of retries', type: :int\n$ mytool --count -1   # '-1' fails /^\\d+$/\n\n# after\n$ mytool --count 5\n# or, if negatives must be supported:\nopt :count, 'Number of retries', type: :string do |v| Integer(v); end","handlingStrategy":"validation","validationCode":"# Trollop only accepts /^\\d+$/ for :int options - check before invoking\nvalue = argv[i + 1]\nabort \"#{value.inspect} is not a valid non-negative integer\" unless value =~ /^\\d+$/","typeGuard":"# Ruby value guard mirroring the parser's rule\ndef trollop_integer?(s)\n  s.is_a?(String) && s =~ /^\\d+$/\nend\n# If you need signed/hex integers, do NOT use type: :int - see the fallback below","tryCatchPattern":"begin\n  opts = parser.parse(argv)\nrescue Puppet::Util::CommandLine::Trollop::CommandlineError => e\n  raise unless e.message.include?('needs an integer')\n  name = e.message[/option '(.+)' needs/, 1]\n  abort \"#{name} accepts only plain digits (no sign, hex, or decimals)\"\nend","preventionTips":["Pass plain non-negative digits to :int options - '-1', '0x1F', '1_000', '1.5' all fail","For negative or hex numbers, declare the option as :string and convert with Integer(value, 10)/(value, 0) in a callback","When generating command lines from numbers, use Integer#to_s without formatting"],"tags":["puppet","trollop","cli","option-parsing","numeric-parsing"],"backgroundTag":"invalid-numeric-option-value","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}