{"record":{"id":"5ebb5a95d90bee85","repo":"puppetlabs/puppet","slug":"unable-to-convert-a-version-range-class-name-to","errorCode":null,"errorMessage":"Unable to convert a #{version_range.class.name} to a SemVerRange","messagePattern":"Unable to convert a #(.+?) to a SemVerRange","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/types/p_sem_ver_range_type.rb","lineNumber":51,"sourceCode":"    end\n  end\n\n  # Creates a {SemanticPuppet::VersionRange} from the given _version_range_ argument. If the argument is `nil` or\n  # a {SemanticPuppet::VersionRange}, it is returned. If it is a {String}, it will be parsed into a\n  # {SemanticPuppet::VersionRange}. Any other class will raise an {ArgumentError}.\n  #\n  # @param version_range [SemanticPuppet::VersionRange,String,nil] the version range to convert\n  # @return [SemanticPuppet::VersionRange] the converted version range\n  # @raise [ArgumentError] when the argument cannot be converted into a version range\n  #\n  def self.convert(version_range)\n    case version_range\n    when nil, SemanticPuppet::VersionRange\n      version_range\n    when String\n      SemanticPuppet::VersionRange.parse(version_range)\n    else\n      raise ArgumentError, \"Unable to convert a #{version_range.class.name} to a SemVerRange\"\n    end\n  end\n\n  # Checks if range _a_ is a sub-range of (i.e. completely covered by) range _b_\n  # @param a [SemanticPuppet::VersionRange] the first range\n  # @param b [SemanticPuppet::VersionRange] the second range\n  #\n  # @return [Boolean] `true` if _a_ is completely covered by _b_\n  def self.covered_by?(a, b)\n    b.begin <= a.begin && (b.end > a.end || b.end == a.end && (!b.exclude_end? || a.exclude_end?))\n  end\n\n  # Merge two ranges so that the result matches all versions matched by both. A merge\n  # is only possible when the ranges are either adjacent or have an overlap.\n  #\n  # @param a [SemanticPuppet::VersionRange] the first range\n  # @param b [SemanticPuppet::VersionRange] the second range\n  # @return [SemanticPuppet::VersionRange,nil] the result of the merge","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/types/p_sem_ver_range_type.rb#L33-L69","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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\")"],"exampleFix":"# before\nPuppet::Pops::Types::PSemVerRangeType.convert(10)      # ArgumentError\n$range = SemVerRange[1]                                 # DSL equivalent\n\n# after\nPuppet::Pops::Types::PSemVerRangeType.convert('>= 10.0')\n$range = SemVerRange['>= 10.0']","handlingStrategy":"type-guard","validationCode":"# accept only nil, VersionRange, or String before calling convert\nunless version_range.nil? || version_range.is_a?(SemanticPuppet::VersionRange) || version_range.is_a?(String)\n  raise ArgumentError, \"expected a SemVer range String or VersionRange, got #{version_range.class}\"\nend","typeGuard":"def semver_range_input?(v)\n  v.nil? || v.is_a?(SemanticPuppet::VersionRange) || v.is_a?(String)\nend","tryCatchPattern":"begin\n  Puppet::Pops::Types::PSemVerRangeType.convert(input)\nrescue ArgumentError => e\n  raise unless e.message =~ /to a SemVerRange/\n  raise \"invalid version range #{input.inspect}: pass a String like '>= 1.0.0 < 2.0.0'\"\nend","preventionTips":["Keep version constraints as Strings end to end (config files, data, code)","Validate range strings with SemanticPuppet::VersionRange.parse at config load time"],"tags":["puppet","semver","type-conversion","ruby"],"backgroundTag":"version-parse-error","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}