puppetlabs/puppet · error · CommandlineError

--%{value0} requires --%{value1}

Error message

--%{value0} requires --%{value1}

What it means

Constraints registered with depends(*syms) are evaluated after token parsing (trollop.rb:399-410): if any member of the group was given on the command line, every other member must also appear, else parse raises CommandlineError '--x requires --y' at line 406 with both long names interpolated from @specs. A :default value does not satisfy a depends constraint — only the literal presence of the flag on the command line counts.

Source

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

        end

        num_params_taken
      end

      if handle_help_and_version
        ## check for version and help args
        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

View on GitHub (pinned to e227c27540)

Solutions

  1. Add the missing partner flag named in the message
  2. Consult --help for dependency notes before running
  3. As the developer, drop the depends constraint and validate in code after parsing so you can emit a clearer, context-aware message

Example fix

# before (tool declared depends :encrypt, :key)
$ mytool --encrypt
Error: --encrypt requires --key

# after
$ mytool --encrypt --key /etc/mytool/key.pem
Defensive patterns

Strategy: try-catch

Validate before calling

# Check depends groups before parse by asking the parser for its constraints
constraints = parser.instance_variable_get(:@constraints)
given = argv.map { |t| t[/^--no-?(.+)/, 1]&.tr('-', '_')&.to_sym }.compact
constraints.select { |type, _| type == :depends }.each do |_, syms|
  next unless (syms & given).any?
  missing = syms - given
  abort "Missing required companion option(s): --#{missing.map { |s| s.to_s.tr('_', '-') }.join(' --')}" unless missing.empty?
end

Try / catch

begin
  opts = parser.parse(argv)
rescue Puppet::Util::CommandLine::Trollop::CommandlineError => e
  raise unless e.message.include?(' requires --')
  partner = e.message[/requires --(.+)$/, 1]
  warn "#{e.message}. Re-running with --#{partner} included."
  retry_with = argv + ["--#{partner}"]
  opts = parser.parse(retry_with)   # only if a sensible default value exists
end

Prevention

When it happens

Trigger: `mytool --encrypt` when the tool declared `depends :encrypt, :key` and --key is absent; giving one member of a paired option set such as --bucket without --bucket-server.

Common situations: Options designed as pairs (mode + target, output + format); users copying a partial example command line; documentation showing only one of the two required flags.

Related errors


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