puppetlabs/puppet · error · Puppet::Util::CommandLine::PuppetOptionError

Error parsing arguments

Error message

Error parsing arguments

What it means

Raised as Puppet::Util::CommandLine::PuppetOptionError by PuppetOptionParser#parse (lib/puppet/util/command_line/puppet_option_parser.rb) when the vendored Trollop parser rejects the argument list. The real reason (unknown option, option missing its value, bad value for a typed option) lives on the wrapped Puppet::Util::CommandLine::Trollop::CommandlineError, passed as the second constructor argument, so it appears as the exception's cause. This is puppet's single wrapper for every CLI argument-parsing failure.

Source

Thrown at lib/puppet/util/command_line/puppet_option_parser.rb:78

          case type
          when :REQUIRED
            options[:type] = :string
          when :NONE
            options[:type] = :flag
          else
            raise PuppetOptionError, _("Unsupported type: '%{type}'") % { type: type }
          end

          @parser.opt long.sub("^--", "").intern, desc, options
        end

        def parse(*args)
          args = args[0] if args.size == 1 and args[0].is_a?(Array)
          args_copy = args.dup
          begin
            @parser.parse args_copy
          rescue Puppet::Util::CommandLine::Trollop::CommandlineError => err
            raise PuppetOptionError.new(_("Error parsing arguments"), err)
          end
        end

        def pass_only_last_value_on_to(block)
          ->(values) { block.call(values.is_a?(Array) ? values.last : values) }
        end
        private :pass_only_last_value_on_to
      end
    end
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Inspect the wrapped cause (e.cause.message, also logged as the child error) for the exact Trollop reason before changing anything
  2. Run the subcommand with --help and diff the accepted options against your command line
  3. Fix or remove the offending argument; quote arguments containing spaces
  4. If driving the parser programmatically for pre-dispatch parsing (where app-specific options are not yet registered), set ignore_invalid_options = true on the parser

Example fix

# before
parser.parse(['--sever', 'puppet.example.com']) # typo'd flag -> PuppetOptionError

# after
begin
  parser.parse(['--server', 'puppet.example.com'])
rescue Puppet::Util::CommandLine::PuppetOptionError => e
  warn "argument error: #{e.cause.message}"
  exit 1
end
Defensive patterns

Strategy: try-catch

Try / catch

begin
  options = parser.parse(args)
rescue Puppet::Util::CommandLine::PuppetOptionError => e
  # real reason is on the wrapped Trollop error
  warn "usage error: #{e.cause.message}"
  exit 64 # EX_USAGE
end

Prevention

When it happens

Trigger: Calling PuppetOptionParser#parse (directly or via any puppet application/face startup) with an unregistered option like --nope; supplying an option that requires a value with no following word (--server with nothing after it); a malformed --key=value pair. Trollop raises CommandlineError and it is immediately re-wrapped here.

Common situations: A typo'd long flag on a puppet subcommand; an option removed in a puppet upgrade still passed by a wrapper script; shell scripts forwarding unquoted user input into a puppet command line; gems embedding puppet's CLI parser with arbitrary ARGV.

Related errors


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