puppetlabs/puppet · error · Puppet::Error
Repeat must be 1 unless periodmatch is 'distance', not '%{pe
Error message
Repeat must be 1 unless periodmatch is 'distance', not '%{period}' What it means
A schedule's `repeat` > 1 is only meaningful when `periodmatch` is 'distance' (periods measured as distance since epoch). The validate raises Puppet::Error "Repeat must be 1 unless periodmatch is 'distance'" (lib/puppet/type/schedule.rb:292) when repeat != 1 and periodmatch is set to something else — in practice 'number' (calendar-matched periods).
Source
Thrown at lib/puppet/type/schedule.rb:292
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
def match?(previous, now)
true
end
end
newparam(:weekday) do
desc <<-EOT
The days of the week in which the schedule should be valid.View on GitHub (pinned to e227c27540)
Solutions
- Set `periodmatch => distance` (the default) when using repeat > 1
- Or keep `repeat => 1` and change `period` granularity instead
- Remove the explicit periodmatch if you actually want distance semantics
Example fix
# before
schedule { 'backups':
period => daily,
periodmatch => number,
repeat => 3,
}
# after
schedule { 'backups':
period => daily,
periodmatch => distance,
repeat => 3,
} Defensive patterns
Strategy: validation
Validate before calling
if $repeat != 1 and $periodmatch != undef and $periodmatch != 'distance' {
fail("repeat > 1 requires periodmatch => distance, got '${periodmatch}'")
} Type guard
def repeat_periodmatch_ok?(repeat, periodmatch) repeat == 1 || periodmatch.to_s == 'distance' end
Try / catch
begin
Puppet::Type.type(:schedule).new(
name: 'x', period: :daily, periodmatch: :number, repeat: 3
)
rescue Puppet::Error => e
raise unless e.message.include?('periodmatch')
# switch periodmatch to :distance or set repeat to 1
end Prevention
- Read the schedule docs: repeat counts per distance-period bucket only
- Single-source schedule definitions instead of composing periodmatch and repeat from different layers
- rspec-puppet compile tests for schedule profiles
When it happens
Trigger: `schedule { 'x': period => daily, periodmatch => number, repeat => 3 }`; setting periodmatch => number in a shared schedule define while another layer sets repeat.
Common situations: Users switching periodmatch to 'number' for calendar semantics while keeping a repeat count; module upgrades that exposed both knobs.
Related errors
- Repeat must be a number
- Cannot have both `ensure => disabled` and `enable_only => tr
- You cannot use "mark" property while "ensure" is one of ["ab
- Invalid hour '%{n}'
- Invalid minute '%{n}'
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/58cb05164db503e2.
Report an issue: GitHub.