puppetlabs/puppet · error · ArgumentError
Cannot compare, as %{other} is not a Rpm Version
Error message
Cannot compare, as %{other} is not a Rpm Version What it means
Rpm#<=> (rpm.rb:42) raises ArgumentError 'Cannot compare, as X is not a Rpm Version' unless other.is_a?(self.class), then delegates to rpm_compare_evr on the string forms (epoch:version-release, epoch treated as zero when absent). eql?/== simply return false for foreign objects, but the spaceship operator must call into the RPM comparison library and refuses anything but another Rpm instance.
Source
Thrown at lib/puppet/util/package/version/rpm.rb:42
version_found = ''.dup
version_found += "#{@epoch}:" if @epoch
version_found += @version
version_found += "-#{@release}" if @release
version_found
end
alias inspect to_s
def eql?(other)
other.is_a?(self.class) &&
@epoch.eql?(other.epoch) &&
@version.eql?(other.version) &&
@release.eql?(other.release) &&
@arch.eql?(other.arch)
end
alias == eql?
def <=>(other)
raise ArgumentError, _("Cannot compare, as %{other} is not a Rpm Version") % { other: other } unless other.is_a?(self.class)
rpm_compare_evr(to_s, other.to_s)
end
private
# overwrite rpm_compare_evr to treat no epoch as zero epoch
# in order to compare version correctly
#
# returns 1 if a is newer than b,
# 0 if they are identical
# -1 if a is older than b
def rpm_compare_evr(a, b)
a_hash = rpm_parse_evr(a)
b_hash = rpm_parse_evr(b)
a_hash[:epoch] ||= '0'
b_hash[:epoch] ||= '0'View on GitHub (pinned to e227c27540)
Solutions
- Parse both sides with Rpm.parse (accepts 'epoch:version-release.arch' shaped strings) before comparing.
- Type-guard comparisons: only call <=> when other.is_a?(Puppet::Util::Package::Version::Rpm).
- Convert foreign versions via their to_s into Rpm.parse when semantically valid.
- Rescue ArgumentError around sort/select blocks that may see mixed types and pre-normalize the array.
Example fix
// before installed = Rpm.parse(pkg_version) outdated = installed < latest_version_string # String -> ArgumentError // after latest = Puppet::Util::Package::Version::Rpm.parse(latest_version_string) outdated = installed < latest
Defensive patterns
Strategy: type-guard
Type guard
RPM = Puppet::Util::Package::Version::Rpm def rpm_pair?(a, b) a.is_a?(RPM) && b.is_a?(RPM) end
Try / catch
begin a <=> b rescue ArgumentError b = RPM.parse(b.to_s) a <=> b end
Prevention
- Parse query output through Rpm.parse on both sides of every comparison.
- Keep per-family arrays (rpm vs debian vs pip) instead of one mixed versions array.
When it happens
Trigger: Puppet::Util::Package::Version::Rpm.parse('1:1.2.3-4.el7') > '1:1.2.3-5.el7' (String rhs); rpm_v < debian_v (cross-family compare); sorting an array mixing Rpm versions with Strings or Gem versions.
Common situations: Package code handling multiple package managers with a single generic comparator; ensure values pulled from RPM query output left as Strings on one side; refactors that changed one operand's parsing but not the other.
Related errors
- #{version} is not a valid ruby gem version.
- Unable to parse '#{range_string}' as a string
- puppet.tasks/unparseable-metadata
- field 'data_provider' must be a string
- Modules are not supported on DNF versions lower than 3.0.1
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/111f2b71183cc32f.
Report an issue: GitHub.