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 merge

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass a range expression as a String: '>= 1.0.0 < 2.0.0', '~> 1.2', '1.x'
  2. Or pass an existing SemanticPuppet::VersionRange object (nil is also accepted and yields the unbounded default)
  3. 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

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


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