{"record":{"id":"100ae78c902f3324","repo":"puppetlabs/puppet","slug":"option-arg-needs-a-date","errorCode":null,"errorMessage":"option '%{arg}' needs a date","messagePattern":"option '%(.+?)' needs a date","errorType":"exception","errorClass":"CommandlineError","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/command_line/trollop.rb","lineNumber":481,"sourceCode":"\n      ## allow openstruct-style accessors\n      class << vals\n        def method_missing(m, *args)\n          self[m] || self[m.to_s]\n        end\n      end\n      vals\n    end\n\n    def parse_date_parameter param, arg # :nodoc:\n      begin\n        time = Chronic.parse(param)\n      rescue NameError\n        # chronic is not available\n      end\n      time ? Date.new(time.year, time.month, time.day) : Date.parse(param)\n    rescue ArgumentError => e\n      raise CommandlineError, _(\"option '%{arg}' needs a date\") % { arg: arg }, e.backtrace\n    end\n\n    ## Print the help message to +stream+.\n    def educate stream = $stdout\n      width # just calculate it now; otherwise we have to be careful not to\n      # call this unless the cursor's at the beginning of a line.\n\n      left = {}\n      @specs.each do |name, spec|\n        left[name] = \"--#{spec[:long]}\" +\n                     (spec[:short] && spec[:short] != :none ? \", -#{spec[:short]}\" : \"\") +\n                     case spec[:type]\n                     when :flag; \"\"\n                     when :int; \" <i>\"\n                     when :ints; \" <i+>\"\n                     when :string; \" <s>\"\n                     when :strings; \" <s+>\"\n                     when :float; \" <f>\"","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/command_line/trollop.rb#L463-L499","documentation":"Options typed :date (or :dates) parse each parameter with parse_date_parameter (trollop.rb:474-482): it tries Chronic.parse when the chronic gem is available (rescuing NameError when it is not), then falls back to Date.parse; if both fail with ArgumentError it re-raises CommandlineError \"option '--x' needs a date\", preserving the original backtrace. Behavior therefore differs by environment — natural-language dates like 'yesterday' only parse when chronic is installed.","triggerScenarios":"`mytool --until someday` (unparseable by both parsers); `--until yesterday` on a system without the chronic gem, because plain Date.parse rejects it; ambiguous strings like '13/13/2020' that Date.parse cannot resolve.","commonSituations":"Assuming natural-language dates work because they did on a dev box that had chronic; locale-dependent date formats (DD/MM vs MM/DD) failing Date.parse; generated timestamps with trailing whitespace.","solutions":["Use an unambiguous ISO date: `--until 2026-08-21`","Add the chronic gem to the tool's dependencies if natural-language dates are wanted","Validate the value's format before invoking the command when command lines are generated programmatically"],"exampleFix":"# before\n$ mytool --until someday\nError: option '--until' needs a date\n\n# after\n$ mytool --until 2026-08-21","handlingStrategy":"validation","validationCode":"# Validate date params against Date.parse (and Chronic when present) before invoking\nrequire 'date'\ndef parseable_date?(s)\n  return true if defined?(Chronic) && Chronic.parse(s)\n  !!Date.parse(s)\nrescue ArgumentError, TypeError\n  false\nend\n\nvalue = argv[i + 1]\nabort \"Invalid date '#{value}' - use YYYY-MM-DD\" unless parseable_date?(value)","typeGuard":null,"tryCatchPattern":"begin\n  opts = parser.parse(argv)\nrescue Puppet::Util::CommandLine::Trollop::CommandlineError => e\n  raise unless e.message.include?('needs a date')\n  name = e.message[/option '(.+)' needs/, 1]\n  abort \"#{name} needs a parseable date (ISO 8601 like 2026-08-21 always works)\"\nend","preventionTips":["Standardize on ISO dates (YYYY-MM-DD) in scripts and generated command lines","If natural-language dates are required, declare chronic as a hard dependency of the tool","Validate date strings with Date.parse in the caller before shelling out"],"tags":["puppet","trollop","cli","option-parsing","date-parsing"],"backgroundTag":"invalid-date-format","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}