puppetlabs/puppet · error · CommandlineError

option --%{opt} must be specified

Error message

option --%{opt} must be specified

What it means

Options declared with `required: true` are collected before parsing (trollop.rb:323-324) and checked afterwards at trollop.rb:413: any that were not present on the command line raise CommandlineError 'option --x must be specified'. A :default does not exempt a required option — required means the user must type the flag; the default only fills the value when the option is absent in code paths that read the parsed hash directly.

Source

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

        raise VersionNeeded if given_args.include? :version
        raise HelpNeeded if given_args.include? :help
      end

      ## check constraint satisfaction
      @constraints.each do |type, syms|
        constraint_sym = syms.find { |sym| given_args[sym] }
        next unless constraint_sym

        case type
        when :depends
          syms.each { |sym| raise CommandlineError, _("--%{value0} requires --%{value1}") % { value0: @specs[constraint_sym][:long], value1: @specs[sym][:long] } unless given_args.include? sym }
        when :conflicts
          syms.each { |sym| raise CommandlineError, _("--%{value0} conflicts with --%{value1}") % { value0: @specs[constraint_sym][:long], value1: @specs[sym][:long] } if given_args.include?(sym) && (sym != constraint_sym) }
        end
      end

      required.each do |sym, _val|
        raise CommandlineError, _("option --%{opt} must be specified") % { opt: @specs[sym][:long] } unless given_args.include? sym
      end

      ## parse parameters
      given_args.each do |sym, given_data|
        arg = given_data[:arg]
        params = given_data[:params]

        opts = @specs[sym]
        raise CommandlineError, _("option '%{arg}' needs a parameter") % { arg: arg } if params.empty? && opts[:type] != :flag

        vals["#{sym}_given".intern] = true # mark argument as specified on the commandline

        case opts[:type]
        when :flag
          if arg =~ /^--no-/ and sym.to_s =~ /^--\[no-\]/
            vals[sym] = opts[:default]
          else
            vals[sym] = !opts[:default]

View on GitHub (pinned to e227c27540)

Solutions

  1. Supply the missing flag exactly as named in the message
  2. Check --help for required options before running
  3. If the option should be optional, remove `required: true` and give it a :default
  4. For conditional requirements, validate in code after parsing and emit a targeted message

Example fix

# before
opt :env, 'Target environment', type: :string, required: true
$ mytool deploy
Error: option --env must be specified

# after
$ mytool deploy --env production
# or make it optional:
opt :env, 'Target environment', type: :string, default: 'production'
Defensive patterns

Strategy: try-catch

Validate before calling

# Verify every required option is present before parse
specs = parser.instance_variable_get(:@specs)
required = specs.select { |_, o| o[:required] }.keys
given = argv.map { |t| t[/^--no-?(.+)/, 1]&.tr('-', '_')&.to_sym }.compact
missing = required - given
abort "Missing required option(s): --#{missing.map { |s| s.to_s.tr('_', '-') }.join(' --')}" unless missing.empty?

Try / catch

begin
  opts = parser.parse(argv)
rescue Puppet::Util::CommandLine::Trollop::CommandlineError => e
  raise unless e.message.include?('must be specified')
  # optionality fallback: re-parse with a default injected instead of required
  specs = parser.instance_variable_get(:@specs)
  opt_name = e.message[/option --(.+) must be specified/, 1].tr('-', '_').to_sym
  specs[opt_name][:required] = false
  specs[opt_name][:default] ||= fallback_value_for(opt_name)
  opts = parser.parse(argv)
end

Prevention

When it happens

Trigger: Running a face or subcommand while omitting its required option; a cron job or systemd unit invoking the tool with an incomplete ARGV.

Common situations: First runs without reading --help; environment-specific wrappers dropping arguments; upgrading a tool where a formerly optional flag became required.

Related errors


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