javan/whenever · error · ArgumentError

Couldn't parse: #{@time.inspect}

Error message

Couldn't parse: #{@time.inspect}

What it means

When Whenever cannot express a time as an interval, parse_as_string looks for 'weekday', 'weekend', or a day-name abbreviation (sun, mon, tue, wed, thu, fri, sat) inside the string; raw cron strings were already matched earlier by Cron::REGEX in time_in_cron_syntax. If nothing matches it raises ArgumentError with the inspected input. Unknown symbols such as :fortnight also land here, because parse_symbol only understands the KEYWORDS and the interval symbols before falling through to parse_as_string.

Source

Thrown at lib/whenever/cron.rb:150

        timing.join(' ')
      end

      def parse_as_string
        return unless @time
        string = @time.to_s

        timing = Array.new(4, '*')
        timing[0] = @at.is_a?(Time) ? @at.min  : 0
        timing[1] = @at.is_a?(Time) ? @at.hour : 0

        return (timing << '1-5') * " " if string.downcase.index('weekday')
        return (timing << '6,0') * " " if string.downcase.index('weekend')

        DAYS.each_with_index do |day, i|
          return (timing << i) * " " if string.downcase.index(day)
        end

        raise ArgumentError, "Couldn't parse: #{@time.inspect}"
      end

      def range_or_integer(at, valid_range, name)
        must_be_between = "#{name} must be between #{valid_range.min}-#{valid_range.max}"
        if at.is_a?(Range)
          raise ArgumentError, "#{must_be_between}, #{at.min} given" unless valid_range.include?(at.min)
          raise ArgumentError, "#{must_be_between}, #{at.max} given" unless valid_range.include?(at.max)
          return "#{at.min}-#{at.max}"
        end
        raise ArgumentError, "#{must_be_between}, #{at} given" unless valid_range.include?(at)
        at
      end

      def comma_separated_timing(frequency, max, start = 0)
        return start     if frequency.nil? || frequency == "" || frequency.zero?
        return '*'       if frequency == 1
        return frequency if frequency > (max * 0.5).ceil

View on GitHub (pinned to 756163ed1a)

Solutions

  1. Use the supported symbols: :minute, :hour, :day, :week, :month, :year, or the @ keywords (:hourly, :daily, :midnight, :weekly, :monthly, :yearly, :annually, :reboot).
  2. Use numbers for custom intervals: every 90.minutes, every 2.days.
  3. Use a raw cron string for anything else: every '*/15 * * * *', or a day-containing string such as every 'sunday'.

Example fix

# before
every 'week' do
  rake 'weekly:report'
end

# after
every :week do
  rake 'weekly:report'
end
Defensive patterns

Strategy: type-guard

Validate before calling

raw_cron = /\A(@(reboot|yearly|annually|monthly|weekly|daily|midnight|hourly)|([\d*\/,-]+\s){3}[\d*\/,-]+\s[\d*\/,-]+)\z/i
s = time.to_s.downcase
ok = time.is_a?(Numeric) || (time =~ raw_cron) || %w[weekday weekend sun mon tue wed thu fri sat].any? { |d| s.include?(d) }
abort('unsupported schedule value: ' + time.inspect) unless ok

Type guard

def whenever_time?(t)
  return true if t.is_a?(Numeric)
  return false unless t
  s = t.to_s.downcase
  (t.to_s =~ Whenever::Output::Cron::REGEX) ||
    %w[weekday weekend sun mon tue wed thu fri sat].any? { |d| s.include?(d) }
end

Try / catch

begin
  Whenever.cron(file: 'config/schedule.rb')
rescue ArgumentError => e
  abort('unparseable schedule time: ' + e.message)
end

Prevention

When it happens

Trigger: every 'week' (contains no day abbreviation and is not raw cron); every 'day'; every '1.day' passed as a string; every :fortnight or any symbol outside KEYWORDS and the :year/:month/:week/:day/:hour/:minute set; month-name strings like 'january' (only @: strings are Chronic-parsed — plain time strings are scanned for day names only).

Common situations: Typing durations as quoted Rails idioms ('1.day') copied from elsewhere; inventing symbol shortcuts Whenever does not define; assuming natural-language strings are parsed like :at values are; renaming schedule values during refactoring so a symbol becomes an unsupported string.

Related errors


AI-assisted analysis of javan/whenever@756163ed1a (2026-08-21). Data as JSON: /api/errors/0a926448f2f98066. Report an issue: GitHub.