puppetlabs/puppet · error · CommandlineError

option '%{arg}' needs a date

Error message

option '%{arg}' needs a date

What it means

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.

Source

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

      ## allow openstruct-style accessors
      class << vals
        def method_missing(m, *args)
          self[m] || self[m.to_s]
        end
      end
      vals
    end

    def parse_date_parameter param, arg # :nodoc:
      begin
        time = Chronic.parse(param)
      rescue NameError
        # chronic is not available
      end
      time ? Date.new(time.year, time.month, time.day) : Date.parse(param)
    rescue ArgumentError => e
      raise CommandlineError, _("option '%{arg}' needs a date") % { arg: arg }, e.backtrace
    end

    ## Print the help message to +stream+.
    def educate stream = $stdout
      width # just calculate it now; otherwise we have to be careful not to
      # call this unless the cursor's at the beginning of a line.

      left = {}
      @specs.each do |name, spec|
        left[name] = "--#{spec[:long]}" +
                     (spec[:short] && spec[:short] != :none ? ", -#{spec[:short]}" : "") +
                     case spec[:type]
                     when :flag; ""
                     when :int; " <i>"
                     when :ints; " <i+>"
                     when :string; " <s>"
                     when :strings; " <s+>"
                     when :float; " <f>"

View on GitHub (pinned to e227c27540)

Solutions

  1. Use an unambiguous ISO date: `--until 2026-08-21`
  2. Add the chronic gem to the tool's dependencies if natural-language dates are wanted
  3. Validate the value's format before invoking the command when command lines are generated programmatically

Example fix

# before
$ mytool --until someday
Error: option '--until' needs a date

# after
$ mytool --until 2026-08-21
Defensive patterns

Strategy: validation

Validate before calling

# Validate date params against Date.parse (and Chronic when present) before invoking
require 'date'
def parseable_date?(s)
  return true if defined?(Chronic) && Chronic.parse(s)
  !!Date.parse(s)
rescue ArgumentError, TypeError
  false
end

value = argv[i + 1]
abort "Invalid date '#{value}' - use YYYY-MM-DD" unless parseable_date?(value)

Try / catch

begin
  opts = parser.parse(argv)
rescue Puppet::Util::CommandLine::Trollop::CommandlineError => e
  raise unless e.message.include?('needs a date')
  name = e.message[/option '(.+)' needs/, 1]
  abort "#{name} needs a parseable date (ISO 8601 like 2026-08-21 always works)"
end

Prevention

When it happens

Trigger: `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.

Common situations: 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.

Related errors


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