puppetlabs/puppet · error · ArgumentError

Invalid hour '%{n}'

Error message

Invalid hour '%{n}'

What it means

The schedule type's `range` parameter parses 'HH:MM-HH:MM[:SS]' strings; each endpoint is split on ':' and cast with to_i, minutes/seconds default to 0. Each endpoint's hour must be within 0–23 or ArgumentError "Invalid hour" is raised (lib/puppet/type/schedule.rb:131). Note 24 is invalid — the day wraps to 0.

Source

Thrown at lib/puppet/type/schedule.rb:131

        values.each { |value|
          range = []
          # Split each range value into a hour, minute, second triad
          value.split(/\s*-\s*/).each { |val|
            # Add the values as an array.
            range << val.split(":").collect(&:to_i)
          }

          self.fail _("Invalid range %{value}") % { value: value } if range.length != 2

          # Fill out 0s for unspecified minutes and seconds
          range.each do |time_array|
            (3 - time_array.length).times { |_| time_array << 0 }
          end

          # Make sure the hours are valid
          [range[0][0], range[1][0]].each do |n|
            raise ArgumentError, _("Invalid hour '%{n}'") % { n: n } if n < 0 or n > 23
          end

          [range[0][1], range[1][1]].each do |n|
            raise ArgumentError, _("Invalid minute '%{n}'") % { n: n } if n and (n < 0 or n > 59)
          end
          ret << range
        }

        # Now our array of arrays
        ret
      end

      def weekday_match?(day)
        if @resource[:weekday]
          @resource[:weekday].has_key?(day)
        else
          true
        end

View on GitHub (pinned to e227c27540)

Solutions

  1. Use hours 0–23 only; express end-of-day as 23:59:59
  2. For windows crossing midnight, use two ranges (e.g. '20:00-23:59:59' and '0:00-2:00') since Puppet treats ranges as within a single day
  3. Fix template arithmetic that computes hour 24

Example fix

# before
schedule { 'maintenance':
  range => '20:00-24:00',
}

# after
schedule { 'maintenance':
  range => '20:00-23:59:59',
}
Defensive patterns

Strategy: validation

Validate before calling

[$start_hour, $end_hour].all |Integer $h| { $h >= 0 and $h <= 23 } or
fail('schedule range hours must be 0-23')

Type guard

def valid_hours?(start_h, end_h)
  [start_h, end_h].all? { |h| h.is_a?(Integer) && h.between?(0, 23) }
end

Try / catch

begin
  Puppet::Type.type(:schedule).new(name: 'm', range: '25:00-27:00')
rescue ArgumentError => e
  raise unless e.message.include?("Invalid hour")
  # clamp/fix hours to 0-23 and rebuild
end

Prevention

When it happens

Trigger: `schedule { 'm': range => '25:00-27:00' }`; `range => '20:00-24:00'` (24 out of range — write 23:59:59 or cross midnight with two ranges); computed hours from templates that overflow past 23.

Common situations: Assuming 24:00 means end-of-day; copy-pasting 12-hour times without converting; maintenance-window templates computing `start + duration` that produce 24+.

Related errors


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