puppetlabs/puppet · error · Puppet::Error
Cannot compare #{this} (Array) with #{other} (#{other.class}
Error message
Cannot compare #{this} (Array) with #{other} (#{other.class}). Only ±Float::INFINITY accepted. What it means
Internal invariant guard in Pip.compare (pip.rb:156), reached from Pip#<=>: when the left comparison key ('this') is an Array and the right ('other') is not, the only legal scalar is +Infinity/-Infinity, because #key uses those sentinels for absent pre/post/dev/local segments (see pip.rb:129-142). A finite scalar opposite an Array means the two keys were built inconsistently, and Puppet::Error is raised. Note a non-Numeric scalar would NoMethodError on .abs before this raise even fires.
Source
Thrown at lib/puppet/util/package/version/pip.rb:156
if !local
local_key = [[-Float::INFINITY, ""]]
else
local_key = local.map { |i| (i.is_a? Integer) ? [i, ""] : [-Float::INFINITY, i] }
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
- Only ever obtain Pip instances from Puppet::Util::Package::Version::Pip.parse; never build or mutate @key/@release_data manually.
- Clear/refetch cached version objects after upgrading puppet so keys are rebuilt by the current code.
- Replace test doubles with real parsed instances (Pip.parse('1.0.0rc1') etc.).
- Wrap risky comparisons in rescue Puppet::Error and re-parse both operands once before giving up.
Example fix
// before def compare_versions(a, b) a <=> b # a.key was hand-built and now holds a finite Integer where b has an Array end // after def compare_versions(a, b) a = Puppet::Util::Package::Version::Pip.parse(a.to_s) b = Puppet::Util::Package::Version::Pip.parse(b.to_s) a <=> b end
Defensive patterns
Strategy: type-guard
Type guard
PIP = Puppet::Util::Package::Version::Pip def safely_comparable?(a, b) a.is_a?(PIP) && b.is_a?(PIP) && !a.instance_variable_get(:@key).nil? && !b.instance_variable_get(:@key).nil? end
Try / catch
begin
a <=> b
rescue Puppet::Error => e
raise unless e.message.include?('Only ±Float::INFINITY')
a = PIP.parse(a.to_s); b = PIP.parse(b.to_s)
a <=> b
end Prevention
- Only construct Pip versions via .parse; never assign or mutate key/instance data.
- Use real parsed instances in tests instead of stubs with fabricated keys.
- Include the puppet version in any cache key for parsed version objects so stale keys are never compared.
When it happens
Trigger: Comparing Pip instances whose @key arrays were mutated or hand-built (dup + modify, subclass overriding #key); comparing a parsed version against a same-class object constructed via Pip.new/send bypassing parse; release_key (an Array of Integers, pip.rb:126) meeting a finite Integer at the same slot.
Common situations: Test doubles/stubs of the Pip class that fabricate key data; monkey-patches or cache layers that store and reload partially-serialized version objects; library upgrades where #key changed shape but stale objects from a process-wide cache are still compared.
Related errors
- Cannot compare #{this} (#{this.class}) with #{other} (Array)
- #{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/e789b52c42be210c.
Report an issue: GitHub.