puppetlabs/puppet · error · ArgumentError

invalid short option name '%{name}'

Error message

invalid short option name '%{name}'

What it means

After long-name handling, opt normalizes :short through the case at trollop.rb:236-240. Acceptable forms are nil, :none, a single character, or a '-c' string whose dash is stripped. Any other value — a multi-character string like 'vv', a double-dash '--v', or an empty string — falls to the else branch and raises ArgumentError at line 239.

Source

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

      opts[:long] =
        case opts[:long]
        when /^--([^-].*)$/
          ::Regexp.last_match(1)
        when /^[^-]/
          opts[:long]
        else
          raise ArgumentError, _("invalid long option name %{name}") % { name: opts[:long].inspect }
        end
      raise ArgumentError, _("long option name %{value0} is already taken; please specify a (different) :long") % { value0: opts[:long].inspect } if @long[opts[:long]]

      ## fill in :short
      unless opts[:short] == :none
        opts[:short] = opts[:short].to_s if opts[:short]
      end
      opts[:short] = case opts[:short]
                     when /^-(.)$/; ::Regexp.last_match(1)
                     when nil, :none, /^.$/; opts[:short]
                     else raise ArgumentError, _("invalid short option name '%{name}'") % { name: opts[:short].inspect }
                     end

      if opts[:short]
        raise ArgumentError, _("short option name %{value0} is already taken; please specify a (different) :short") % { value0: opts[:short].inspect } if @short[opts[:short]]
        raise ArgumentError, _("a short option name can't be a number or a dash") if opts[:short] =~ INVALID_SHORT_ARG_REGEX
      end

      ## fill in :default for flags
      opts[:default] = false if opts[:type] == :flag && opts[:default].nil?

      ## autobox :default for :multi (multi-occurrence) arguments
      opts[:default] = [opts[:default]] if opts[:default] && opts[:multi] && !opts[:default].is_a?(Array)

      ## fill in :multi
      opts[:multi] ||= false

      opts[:desc] ||= desc
      @long[opts[:long]] = name

View on GitHub (pinned to e227c27540)

Solutions

  1. Use a single character: `short: 'v'` or `short: '-v'`
  2. Pass `short: :none` when the option should have no short form at all
  3. Express multi-letter flags as a long option instead of a short one

Example fix

# before
opt :verbosity, 'Verbosity', short: '-vv'

# after
opt :verbosity, 'Verbosity', short: '-v'
Defensive patterns

Strategy: validation

Validate before calling

# Validate a :short spec before opt
def valid_short?(short)
  short.nil? || short == :none || short.to_s =~ /^-(.)$/ || short.to_s =~ /^.$/
end

raise ArgumentError, "bad short #{opts[:short].inspect}" unless valid_short?(opts[:short])

Try / catch

begin
  parser.opt name, desc, short: candidate
rescue ArgumentError => e
  raise unless e.message.include?('invalid short option name')
  parser.opt name, desc, short: :none   # degrade to long-only
end

Prevention

When it happens

Trigger: `short: '-vv'`, `short: 'vx'`, `short: '--v'`, `short: ''`.

Common situations: Trying to declare a multi-letter bundled flag as a 'short' name; OptionParser habits where looser strings were tolerated; typos in hand-written option declarations.

Related errors


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