puppetlabs/puppet · error · Puppet::Error
Cannot compare #{this} (#{this.class}) with #{other} (Array)
Error message
Cannot compare #{this} (#{this.class}) with #{other} (Array). Only ±Float::INFINITY accepted. What it means
Mirror of the previous guard in Pip.compare (pip.rb:160): the LEFT comparison key is a non-Array scalar and the RIGHT is an Array. The scalar must be +/- Float::INFINITY (the sentinel used by #key for missing segments); any finite value raises Puppet::Error 'Only ±Float::INFINITY accepted.' before the comparison can proceed.
Source
Thrown at lib/puppet/util/package/version/pip.rb:160
end
[epoch, release_key, pre_key, post_key, dev_key, local_key]
end
def compare(this, other)
if (this.is_a? Array) && (other.is_a? Array)
this << -Float::INFINITY if this.length < other.length
other << -Float::INFINITY if this.length > other.length
this.each_with_index do |element, index|
return compare(element, other.at(index)) if element != other.at(index)
end
elsif (this.is_a? Array) && !(other.is_a? Array)
raise Puppet::Error, "Cannot compare #{this} (Array) with #{other} (#{other.class}). Only ±Float::INFINITY accepted." unless other.abs == Float::INFINITY
return other == -Float::INFINITY ? 1 : -1
elsif !(this.is_a? Array) && (other.is_a? Array)
raise Puppet::Error, "Cannot compare #{this} (#{this.class}) with #{other} (Array). Only ±Float::INFINITY accepted." unless this.abs == Float::INFINITY
return this == -Float::INFINITY ? -1 : 1
end
this <=> other
end
class ValidationFailure < ArgumentError
def initialize(version)
super("#{version} is not a valid python package version. Please refer to https://www.python.org/dev/peps/pep-0440/.")
end
end
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Rebuild both operands via Pip.parse immediately before comparing; never compare cached/stubbed key data.
- Freeze/re-parse cache entries when the library version changes; include the puppet version in the cache key.
- In specs, use parsed instances instead of objects with fabricated instance variables.
- Rescue Puppet::Error at the comparison boundary and re-parse once as a recovery path.
Example fix
// before
sorted = cached_versions.sort # one entry has a stale scalar key element
// after
sorted = cached_versions.map { |v| Puppet::Util::Package::Version::Pip.parse(v.to_s) }.sort Defensive patterns
Strategy: type-guard
Type guard
PIP = Puppet::Util::Package::Version::Pip
def pip_instances?(*versions)
versions.all? { |v| v.is_a?(PIP) }
end Try / catch
begin
sorted = versions.sort
rescue Puppet::Error => e
raise unless e.message.include?('Only ±Float::INFINITY')
versions.map! { |v| PIP.parse(v.to_s) }
retry
end Prevention
- Re-parse both operands from to_s before comparing when any doubt exists about their origin.
- Avoid monkey-patching or dup-and-mutating version objects.
- Fail loudly in dev when key shapes differ instead of letting sort blow up in production.
When it happens
Trigger: Same shape as 1006 with sides swapped: comparing a hand-built/stale key whose slot holds a finite Integer/Float (e.g., an epoch-style number left in the release position) against a properly parsed version whose release/local key is an Array; a stubbed peer object returning a scalar from #key where the real class returns an Array.
Common situations: Stale serialized version objects compared after a puppet upgrade changed #key's shape; test fixtures constructing key arrays by hand; caches (memoization) shared across versions of the class.
Related errors
- Cannot compare #{this} (Array) with #{other} (#{other.class}
- #{version} is not a valid python package version. Please ref
- Cannot resolve pip version
- Cannot compare, as %{other} is not a Rpm Version
- Missing operation (-, =, or +)
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/1b5f33b2c4117deb.
Report an issue: GitHub.