puppetlabs/puppet · error · ArgumentError
A Timespan cannot be divided by %{klass}
Error message
A Timespan cannot be divided by %{klass} What it means
Timespan#div (and #/) handles exactly three operand kinds: another Timespan (returns a Float ratio of nanosecond counts), or Integer/Float (returns a new Timespan of @nsecs.div(o)). Everything else raises 'A Timespan cannot be divided by %{klass}'.
Source
Thrown at lib/puppet/pops/time/timespan.rb:194
end
def modulo(o)
divmod(o)[1]
end
def %(o)
modulo(o)
end
def div(o)
case o
when Timespan
# Timespan/Timespan yields a Float
@nsecs.fdiv(o.nsecs)
when Integer, Float
Timespan.new(@nsecs.div(o))
else
raise ArgumentError, _("A Timespan cannot be divided by %{klass}") % { klass: a_an(o) }
end
end
def /(o)
div(o)
end
# @return [Integer] a positive integer denoting the number of days
def days
total_days
end
# @return [Integer] a positive integer, 0 - 23 denoting hours of day
def hours
total_hours % 24
end
# @return [Integer] a positive integer, 0 - 59 denoting minutes of hourView on GitHub (pinned to e227c27540)
Solutions
- Convert the divisor: ts / divisor.to_i (or to_f)
- For 'how many whole times does X fit into this span', divide by a Timespan: span / Timespan(0, 900) gives a Float count
- nil-check optional inputs before dividing
- Wrap division of untrusted values with a rescue ArgumentError that re-raises with the variable name for easier diagnosis
Example fix
// before per_node = total_span / node_count # node_count is a String from JSON // after per_node = total_span / Integer(node_count)
Defensive patterns
Strategy: type-guard
Validate before calling
unless divisor.is_a?(Puppet::Pops::Time::Timespan) || divisor.is_a?(Integer) || divisor.is_a?(Float)
raise ArgumentError, "divisor must be Timespan/Integer/Float, got #{divisor.class}"
end
result = ts / divisor Type guard
def timespan_divisor?(o) o.is_a?(Puppet::Pops::Time::Timespan) || o.is_a?(Integer) || o.is_a?(Float) end
Try / catch
begin
ts / divisor
rescue ArgumentError => e
raise DataError, "bad divisor #{divisor.inspect}"
end Prevention
- Divide by a Timespan when you want a ratio; by a number when you want a shorter Timespan
- Integer() coercion at the config boundary removes the String-divisor class of failure
- nil-check optional counts before averaging durations
When it happens
Trigger: ts / '2', ts / nil, ts / zero-string, or ts / a Timestamp. Also format strings aside, Puppet DSL $span / $n where $n is a String.
Common situations: Averaging durations with a count read from external inventory data (String); dividing by a Puppet Sensitive-wrapped number; attempting Timespan / Timestamp expecting a duration (undefined - subtract two Timestamps instead).
Related errors
- %{klass} cannot be added to a Timespan
- %{klass} cannot be subtracted from a Timespan
- Can not do modulus on a Timespan using a %{klass}
- Format must be a String
- A Timestamp cannot be multiplied by %{klass}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/670849428c650936.
Report an issue: GitHub.