{"record":{"id":"5e6c707510b44105","repo":"puppetlabs/puppet","slug":"option-opt-must-be-specified","errorCode":null,"errorMessage":"option --%{opt} must be specified","messagePattern":"option --%(.+?) must be specified","errorType":"exception","errorClass":"CommandlineError","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/command_line/trollop.rb","lineNumber":413,"sourceCode":"        raise VersionNeeded if given_args.include? :version\n        raise HelpNeeded if given_args.include? :help\n      end\n\n      ## check constraint satisfaction\n      @constraints.each do |type, syms|\n        constraint_sym = syms.find { |sym| given_args[sym] }\n        next unless constraint_sym\n\n        case type\n        when :depends\n          syms.each { |sym| raise CommandlineError, _(\"--%{value0} requires --%{value1}\") % { value0: @specs[constraint_sym][:long], value1: @specs[sym][:long] } unless given_args.include? sym }\n        when :conflicts\n          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) }\n        end\n      end\n\n      required.each do |sym, _val|\n        raise CommandlineError, _(\"option --%{opt} must be specified\") % { opt: @specs[sym][:long] } unless given_args.include? sym\n      end\n\n      ## parse parameters\n      given_args.each do |sym, given_data|\n        arg = given_data[:arg]\n        params = given_data[:params]\n\n        opts = @specs[sym]\n        raise CommandlineError, _(\"option '%{arg}' needs a parameter\") % { arg: arg } if params.empty? && opts[:type] != :flag\n\n        vals[\"#{sym}_given\".intern] = true # mark argument as specified on the commandline\n\n        case opts[:type]\n        when :flag\n          if arg =~ /^--no-/ and sym.to_s =~ /^--\\[no-\\]/\n            vals[sym] = opts[:default]\n          else\n            vals[sym] = !opts[:default]","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/command_line/trollop.rb#L395-L431","documentation":"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.","triggerScenarios":"Running a face or subcommand while omitting its required option; a cron job or systemd unit invoking the tool with an incomplete ARGV.","commonSituations":"First runs without reading --help; environment-specific wrappers dropping arguments; upgrading a tool where a formerly optional flag became required.","solutions":["Supply the missing flag exactly as named in the message","Check --help for required options before running","If the option should be optional, remove `required: true` and give it a :default","For conditional requirements, validate in code after parsing and emit a targeted message"],"exampleFix":"# before\nopt :env, 'Target environment', type: :string, required: true\n$ mytool deploy\nError: option --env must be specified\n\n# after\n$ mytool deploy --env production\n# or make it optional:\nopt :env, 'Target environment', type: :string, default: 'production'","handlingStrategy":"try-catch","validationCode":"# Verify every required option is present before parse\nspecs = parser.instance_variable_get(:@specs)\nrequired = specs.select { |_, o| o[:required] }.keys\ngiven = argv.map { |t| t[/^--no-?(.+)/, 1]&.tr('-', '_')&.to_sym }.compact\nmissing = required - given\nabort \"Missing required option(s): --#{missing.map { |s| s.to_s.tr('_', '-') }.join(' --')}\" unless missing.empty?","typeGuard":null,"tryCatchPattern":"begin\n  opts = parser.parse(argv)\nrescue Puppet::Util::CommandLine::Trollop::CommandlineError => e\n  raise unless e.message.include?('must be specified')\n  # optionality fallback: re-parse with a default injected instead of required\n  specs = parser.instance_variable_get(:@specs)\n  opt_name = e.message[/option --(.+) must be specified/, 1].tr('-', '_').to_sym\n  specs[opt_name][:required] = false\n  specs[opt_name][:default] ||= fallback_value_for(opt_name)\n  opts = parser.parse(argv)\nend","preventionTips":["Check --help for required options before running or scripting a command","In cron/systemd units, test the exact command line manually once before scheduling","As a developer, prefer a :default over required: true unless absence is genuinely an error"],"tags":["puppet","trollop","cli","option-parsing","required-option"],"backgroundTag":"missing-required-option","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}