puppetlabs/puppet · error · ArgumentError
Unable to create a #{impl_class.name} from a #{arg.class.nam
Error message
Unable to create a #{impl_class.name} from a #{arg.class.name} What it means
PAbstractTimeDataType#convert_arg accepts only: an instance of the impl class (Timespan/Timestamp), a Hash (via from_hash), nil or :default (unbounded), a String (parsed), and Integer/Float (seconds). Everything else - Array, Symbol, Object - reaches the else branch and raises ArgumentError naming the impl class and the argument's class. (The trailing unless in the source is dead code: nil and :default were already matched above.)
Source
Thrown at lib/puppet/pops/types/p_timespan_type.rb:74
@from == -Float::INFINITY && @to == Float::INFINITY
end
def convert_arg(arg, min)
case arg
when impl_class
arg
when Hash
impl_class.from_hash(arg)
when nil, :default
min ? -Float::INFINITY : Float::INFINITY
when String
impl_class.parse(arg)
when Integer
impl_class.new(arg * Time::NSECS_PER_SEC)
when Float
impl_class.new(arg * Time::NSECS_PER_SEC)
else
raise ArgumentError, "Unable to create a #{impl_class.name} from a #{arg.class.name}" unless arg.nil? || arg == :default
nil
end
end
# Concatenates this range with another range provided that the ranges intersect or
# are adjacent. When that's not the case, this method will return `nil`
#
# @param o [PAbstractTimeDataType] the range to concatenate with this range
# @return [PAbstractTimeDataType,nil] the concatenated range or `nil` when the ranges were apart
# @api public
def merge(o)
if intersect?(o) || adjacent?(o)
new_min = numeric_from <= o.numeric_from ? numeric_from : o.numeric_from
new_max = numeric_to >= o.numeric_to ? numeric_to : o.numeric_to
self.class.new(new_min, new_max)
else
nilView on GitHub (pinned to e227c27540)
Solutions
- Use a supported bound form: Integer/Float seconds ('3600' as 3600), a parseable String like '1:30:00' / ISO-8601, an existing Timespan/Timestamp instance, or a Hash accepted by from_hash
- For field-wise construction prefer the DSL new dispatches (Timespan.new(days, hours, ...) or from_fields_hash) rather than the ranged type constructor
- Coerce unknown input to a canonical value (or nil for unbounded) before passing it as a bound
Example fix
# before Puppet::Pops::Types::PTimespanType.new(nil, [:hours, 1]) # Array bound -> ArgumentError # after Puppet::Pops::Types::PTimespanType.new(nil, 3600) # Float/Integer seconds # or: PTimespanType.new(nil, '1:00:00') # parseable String # or: Timespan.from_fields(false, 0, 1, 0, 0) # field-wise construction
Defensive patterns
Strategy: type-guard
Validate before calling
# only pass bound forms convert_arg understands
allowed = [String, Integer, Float, Hash]
unless arg.nil? || arg == :default || allowed.any? { |c| arg.is_a?(c) } || arg.is_a?(Puppet::Pops::Time::Timespan)
raise ArgumentError, "unsupported bound #{arg.class}; use String/Integer/Float seconds, Hash, or a Timespan"
end Type guard
def time_bound_input?(arg)
arg.nil? || arg == :default ||
[String, Integer, Float, Hash].any? { |c| arg.is_a?(c) } ||
arg.is_a?(Puppet::Pops::Time::Timespan) || arg.is_a?(Puppet::Pops::Time::Timestamp)
end Try / catch
begin
Puppet::Pops::Types::PTimespanType.new(from_arg, to_arg)
rescue ArgumentError => e
raise unless e.message =~ /Unable to create a .* from a /
raise "bad time bound #{to_arg.inspect}: pass seconds (Numeric), a parseable String, a Hash, or nil"
end Prevention
- Canonicalize time bounds to Integer/Float seconds or ISO strings at your data boundary
- Prefer the field-wise constructors (from_fields, from_hash) for structured input
When it happens
Trigger: Ruby-side construction of a ranged time type with an unsupported bound object: PTimespanType.new(nil, [:hours, 1]), PTimestampType.new(:now, nil). Also reachable from serialized/pcore data where a bound deserialized as an Array or Hash-with-wrong-shape is passed to convert_arg.
Common situations: Programmatically building Timespan/Timestamp bounds from structured data (arrays of parts) instead of the accepted forms; passing :now or custom sentinel symbols; Hash bounds whose keys do not match from_hash's expectations surfacing here only after other errors.
Related errors
- Unable to convert a #{version_range.class.name} to a SemVerR
- Unable to convert a #{version.class.name} to a SemVer
- 'from' must be less or equal to 'to'. Got (#{@from}, #{@to}
- Puppet #{Puppet.version} requires Ruby #{Puppet::OLDEST_RECO
- Invalid entry at %{error_location}: '%{file_text}'
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/551ab8a840cfd1c4.
Report an issue: GitHub.