{"record":{"id":"111f2b71183cc32f","repo":"puppetlabs/puppet","slug":"cannot-compare-as-other-is-not-a-rpm-version","errorCode":null,"errorMessage":"Cannot compare, as %{other} is not a Rpm Version","messagePattern":"Cannot compare, as %(.+?) is not a Rpm Version","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/package/version/rpm.rb","lineNumber":42,"sourceCode":"      version_found = ''.dup\n      version_found += \"#{@epoch}:\" if @epoch\n      version_found += @version\n      version_found += \"-#{@release}\" if @release\n      version_found\n    end\n    alias inspect to_s\n\n    def eql?(other)\n      other.is_a?(self.class) &&\n        @epoch.eql?(other.epoch) &&\n        @version.eql?(other.version) &&\n        @release.eql?(other.release) &&\n        @arch.eql?(other.arch)\n    end\n    alias == eql?\n\n    def <=>(other)\n      raise ArgumentError, _(\"Cannot compare, as %{other} is not a Rpm Version\") % { other: other } unless other.is_a?(self.class)\n\n      rpm_compare_evr(to_s, other.to_s)\n    end\n\n    private\n\n    # overwrite rpm_compare_evr to treat no epoch as zero epoch\n    # in order to compare version correctly\n    #\n    # returns 1 if a is newer than b,\n    #         0 if they are identical\n    #        -1 if a is older than b\n    def rpm_compare_evr(a, b)\n      a_hash = rpm_parse_evr(a)\n      b_hash = rpm_parse_evr(b)\n\n      a_hash[:epoch] ||= '0'\n      b_hash[:epoch] ||= '0'","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/package/version/rpm.rb#L24-L60","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ninstalled = Rpm.parse(pkg_version)\noutdated = installed < latest_version_string # String -> ArgumentError\n\n// after\nlatest = Puppet::Util::Package::Version::Rpm.parse(latest_version_string)\noutdated = installed < latest","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"RPM = Puppet::Util::Package::Version::Rpm\ndef rpm_pair?(a, b)\n  a.is_a?(RPM) && b.is_a?(RPM)\nend","tryCatchPattern":"begin\n  a <=> b\nrescue ArgumentError\n  b = RPM.parse(b.to_s)\n  a <=> b\nend","preventionTips":["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."],"tags":["rpm","puppet","package-version","version-comparison","type-error","spaceship-operator"],"backgroundTag":"incomparable-types","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}