puppetlabs/puppet · error · ArgumentError
Unable to convert a #{version_range.class.name} to a SemVerR
Error message
Unable to convert a #{version_range.class.name} to a SemVerRange What it means
PSemVerRangeType.convert normalizes constructor input for the SemVerRange type: nil and SemanticPuppet::VersionRange pass through, Strings are parsed via SemanticPuppet::VersionRange.parse, and any other class raises ArgumentError stating it cannot be converted to a SemVerRange.
Source
Thrown at lib/puppet/pops/types/p_sem_ver_range_type.rb:51
end
end
# Creates a {SemanticPuppet::VersionRange} from the given _version_range_ argument. If the argument is `nil` or
# a {SemanticPuppet::VersionRange}, it is returned. If it is a {String}, it will be parsed into a
# {SemanticPuppet::VersionRange}. Any other class will raise an {ArgumentError}.
#
# @param version_range [SemanticPuppet::VersionRange,String,nil] the version range to convert
# @return [SemanticPuppet::VersionRange] the converted version range
# @raise [ArgumentError] when the argument cannot be converted into a version range
#
def self.convert(version_range)
case version_range
when nil, SemanticPuppet::VersionRange
version_range
when String
SemanticPuppet::VersionRange.parse(version_range)
else
raise ArgumentError, "Unable to convert a #{version_range.class.name} to a SemVerRange"
end
end
# Checks if range _a_ is a sub-range of (i.e. completely covered by) range _b_
# @param a [SemanticPuppet::VersionRange] the first range
# @param b [SemanticPuppet::VersionRange] the second range
#
# @return [Boolean] `true` if _a_ is completely covered by _b_
def self.covered_by?(a, b)
b.begin <= a.begin && (b.end > a.end || b.end == a.end && (!b.exclude_end? || a.exclude_end?))
end
# Merge two ranges so that the result matches all versions matched by both. A merge
# is only possible when the ranges are either adjacent or have an overlap.
#
# @param a [SemanticPuppet::VersionRange] the first range
# @param b [SemanticPuppet::VersionRange] the second range
# @return [SemanticPuppet::VersionRange,nil] the result of the mergeView on GitHub (pinned to e227c27540)
Solutions
- Pass a range expression as a String: '>= 1.0.0 < 2.0.0', '~> 1.2', '1.x'
- Or pass an existing SemanticPuppet::VersionRange object (nil is also accepted and yields the unbounded default)
- If the source data is numeric, convert it to a String first (e.g. ">= #{major}.0.0")
Example fix
# before
Puppet::Pops::Types::PSemVerRangeType.convert(10) # ArgumentError
$range = SemVerRange[1] # DSL equivalent
# after
Puppet::Pops::Types::PSemVerRangeType.convert('>= 10.0')
$range = SemVerRange['>= 10.0'] Defensive patterns
Strategy: type-guard
Validate before calling
# accept only nil, VersionRange, or String before calling convert
unless version_range.nil? || version_range.is_a?(SemanticPuppet::VersionRange) || version_range.is_a?(String)
raise ArgumentError, "expected a SemVer range String or VersionRange, got #{version_range.class}"
end Type guard
def semver_range_input?(v) v.nil? || v.is_a?(SemanticPuppet::VersionRange) || v.is_a?(String) end
Try / catch
begin
Puppet::Pops::Types::PSemVerRangeType.convert(input)
rescue ArgumentError => e
raise unless e.message =~ /to a SemVerRange/
raise "invalid version range #{input.inspect}: pass a String like '>= 1.0.0 < 2.0.0'"
end Prevention
- Keep version constraints as Strings end to end (config files, data, code)
- Validate range strings with SemanticPuppet::VersionRange.parse at config load time
When it happens
Trigger: Ruby-side: Puppet::Pops::Types::PSemVerRangeType.convert(10), convert(:full), or convert(['>=1.0.0']). DSL-side: constructing SemVerRange with a non-string argument, e.g. SemVerRange[1] or SemVerRange[true], because the type's new function funnels through convert.
Common situations: Passing an Integer pair or a Version where a range is required (SemVer vs SemVerRange confusion); building version constraints from JSON/YAML data where numbers were parsed as numerics; interpolating variables that are nil-with-default sentinels of the wrong kind.
Related errors
- Unable to convert a #{version.class.name} to a SemVer
- Unable to create a #{impl_class.name} from a #{arg.class.nam
- Puppet #{Puppet.version} requires Ruby #{Puppet::OLDEST_RECO
- Invalid entry at %{error_location}: '%{file_text}'
- %{mount} is already mounted at %{name} at %{error_location}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/5ebb5a95d90bee85.
Report an issue: GitHub.