puppetlabs/puppet · error · ArgumentError
short option name %{value0} is already taken; please specify
Error message
short option name %{value0} is already taken; please specify a (different) :short What it means
The parser keeps an @short registry mapping single characters to option symbols. Once :short is normalized to a character, opt raises ArgumentError at trollop.rb:243 if that character is already claimed by another option. Matching is exact per character, so 'v' and 'V' are distinct and can coexist. PuppetOptionParser registers its options without :short, so inside the puppet executable this only fires on explicit duplicate declarations.
Source
Thrown at lib/puppet/util/command_line/trollop.rb:243
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
@short[opts[:short]] = name if opts[:short] && opts[:short] != :none
@specs[name] = opts
@order << [:opt, name]
endView on GitHub (pinned to e227c27540)
Solutions
- Give the second option a different, unused letter
- Set `short: :none` on one of the two options
- Leave :short unset on one option so Trollop derives a free letter from its long name
Example fix
# before opt :verbose, 'Verbose', short: 'v' opt :version, 'Version', short: 'v' # 'v' already taken -> raise # after opt :verbose, 'Verbose', short: 'v' opt :version, 'Version', short: 'V'
Defensive patterns
Strategy: validation
Validate before calling
# Track claimed short characters and check before declaring
claimed = {} # char => option name
char = opts[:short].to_s.sub(/^-/, '')
if claimed.key?(char)
raise ArgumentError, "short '-#{char}' already used by #{claimed[char]}"
end
claimed[char] = name unless char.empty? || opts[:short] == :none Try / catch
begin
parser.opt name, desc, short: candidate
rescue ArgumentError => e
raise unless e.message.include?('short option name') && e.message.include?('already taken')
parser.opt name, desc, short: :none
end Prevention
- Keep a single registry/table of short letters per CLI and review it in code review
- Leave :short unset when unsure - Trollop can derive a free letter from the long name
- Test parser construction after monkey-patching a face so letter collisions surface early
When it happens
Trigger: Two options both declared with `short: 'v'`; reopening a face/application whose option already claimed the letter; a shared option module declaring the same letter in two parsers built from the same spec list.
Common situations: Monkey-patching an existing CLI whose letter is taken; copy-pasting option declarations between faces without checking the letters already in use.
Related errors
- long option name %{value0} is already taken; please specify
- option '%{arg}' specified multiple times
- unsupported argument type '%{value0}'
- :type specification and default type don't match (default ty
- invalid long option name %{name}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/d38608c6da0ad12c.
Report an issue: GitHub.