puppetlabs/puppet · error · Puppet::Error

Repeat must be a number

Error message

Repeat must be a number

What it means

The schedule type's `repeat` parameter (applications allowed per period) validates that the value is an Integer or a digit-only string; otherwise Puppet::Error "Repeat must be a number" (lib/puppet/type/schedule.rb:283). Note the regex has no minus sign or decimal point: '-1' and '1.5' fail, and a Ruby Float like 2.0 fails both checks too.

Source

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

          # If the number of seconds between the two times is greater
          # than the unit of time, we match.  We divide the scale
          # by the repeat, so that we'll repeat that often within
          # the scale.
          (now.to_i - previous.to_i) >= (scale / @resource[:repeat])
        end
      end
    end

    newparam(:repeat) do
      desc "How often a given resource may be applied in this schedule's `period`.
        Must be an integer."

      defaultto 1

      validate do |value|
        unless value.is_a?(Integer) or value =~ /^\d+$/
          raise Puppet::Error,
                _("Repeat must be a number")
        end

        # This implicitly assumes that 'periodmatch' is distance -- that
        # is, if there's no value, we assume it's a valid value.
        return unless @resource[:periodmatch]

        if value != 1 and @resource[:periodmatch] != :distance
          raise Puppet::Error,
                _("Repeat must be 1 unless periodmatch is 'distance', not '%{period}'") % { period: @resource[:periodmatch] }
        end
      end

      munge do |value|
        value = Integer(value) unless value.is_a?(Integer)

        value
      end

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass a plain integer or digit-only string, e.g. repeat => 2
  2. Fix the data source: cast to Integer in profile code or correct the YAML to an int
  3. For finer granularity, shorten `period` instead of using fractional repeat

Example fix

# before
schedule { 'backups':
  period => hourly,
  repeat => '1.5',
}

# after
schedule { 'backups':
  period => hourly,
  repeat => 1,
}
Defensive patterns

Strategy: validation

Validate before calling

$repeat = Integer.new($repeat_raw) # fails early with a clear message
if $repeat < 1 { fail('repeat must be >= 1') }

Type guard

def valid_repeat?(v)
  v.is_a?(Integer) || (v.is_a?(String) && v =~ /\A\d+\z/)
end

Try / catch

begin
  Puppet::Type.type(:schedule).new(name: 'm', period: :hourly, repeat: '1.5')
rescue Puppet::Error => e
  raise unless e.message.include?('Repeat must be a number')
  # Integer()-coerce the value and rebuild
end

Prevention

When it happens

Trigger: `schedule { 'm': period => hourly, repeat => '1.5' }`; `repeat => 'always'`; `repeat => 2.0` (Float literal from YAML); `repeat => -1`.

Common situations: YAML-loaded values becoming Floats (2.0 instead of 2); users wanting fractional frequency; passing words from a UI dropdown.

Related errors


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