{"record":{"id":"0a926448f2f98066","repo":"javan/whenever","slug":"couldn-t-parse-time-inspect","errorCode":null,"errorMessage":"Couldn't parse: #{@time.inspect}","messagePattern":"Couldn't parse: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/whenever/cron.rb","lineNumber":150,"sourceCode":"        timing.join(' ')\n      end\n\n      def parse_as_string\n        return unless @time\n        string = @time.to_s\n\n        timing = Array.new(4, '*')\n        timing[0] = @at.is_a?(Time) ? @at.min  : 0\n        timing[1] = @at.is_a?(Time) ? @at.hour : 0\n\n        return (timing << '1-5') * \" \" if string.downcase.index('weekday')\n        return (timing << '6,0') * \" \" if string.downcase.index('weekend')\n\n        DAYS.each_with_index do |day, i|\n          return (timing << i) * \" \" if string.downcase.index(day)\n        end\n\n        raise ArgumentError, \"Couldn't parse: #{@time.inspect}\"\n      end\n\n      def range_or_integer(at, valid_range, name)\n        must_be_between = \"#{name} must be between #{valid_range.min}-#{valid_range.max}\"\n        if at.is_a?(Range)\n          raise ArgumentError, \"#{must_be_between}, #{at.min} given\" unless valid_range.include?(at.min)\n          raise ArgumentError, \"#{must_be_between}, #{at.max} given\" unless valid_range.include?(at.max)\n          return \"#{at.min}-#{at.max}\"\n        end\n        raise ArgumentError, \"#{must_be_between}, #{at} given\" unless valid_range.include?(at)\n        at\n      end\n\n      def comma_separated_timing(frequency, max, start = 0)\n        return start     if frequency.nil? || frequency == \"\" || frequency.zero?\n        return '*'       if frequency == 1\n        return frequency if frequency > (max * 0.5).ceil\n","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/javan/whenever/blob/756163ed1aa928c8abd629aa2f4904bc5226538c/lib/whenever/cron.rb#L132-L168","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Use the supported symbols: :minute, :hour, :day, :week, :month, :year, or the @ keywords (:hourly, :daily, :midnight, :weekly, :monthly, :yearly, :annually, :reboot).","Use numbers for custom intervals: every 90.minutes, every 2.days.","Use a raw cron string for anything else: every '*/15 * * * *', or a day-containing string such as every 'sunday'."],"exampleFix":"# before\nevery 'week' do\n  rake 'weekly:report'\nend\n\n# after\nevery :week do\n  rake 'weekly:report'\nend","handlingStrategy":"type-guard","validationCode":"raw_cron = /\\A(@(reboot|yearly|annually|monthly|weekly|daily|midnight|hourly)|([\\d*\\/,-]+\\s){3}[\\d*\\/,-]+\\s[\\d*\\/,-]+)\\z/i\ns = time.to_s.downcase\nok = time.is_a?(Numeric) || (time =~ raw_cron) || %w[weekday weekend sun mon tue wed thu fri sat].any? { |d| s.include?(d) }\nabort('unsupported schedule value: ' + time.inspect) unless ok","typeGuard":"def whenever_time?(t)\n  return true if t.is_a?(Numeric)\n  return false unless t\n  s = t.to_s.downcase\n  (t.to_s =~ Whenever::Output::Cron::REGEX) ||\n    %w[weekday weekend sun mon tue wed thu fri sat].any? { |d| s.include?(d) }\nend","tryCatchPattern":"begin\n  Whenever.cron(file: 'config/schedule.rb')\nrescue ArgumentError => e\n  abort('unparseable schedule time: ' + e.message)\nend","preventionTips":["Prefer symbols (:day, :week) or numbers (90.minutes) over invented strings for intervals.","Use raw cron strings ('*/15 * * * *') when the interval is irregular.","Run `whenever` locally after editing schedule values — parse failures print immediately with the offending value."],"tags":["ruby","cron","scheduling","dsl","argumenterror","time-parsing"],"backgroundTag":"schedule-expression-parse-error","analyzedSha":"756163ed1aa928c8abd629aa2f4904bc5226538c","analyzedAt":"2026-08-21T18:07:39.974Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}