puppetlabs/puppet · error · ValidationFailure

#{version} is not a valid ruby gem version.

Error message

#{version} is not a valid ruby gem version.

What it means

First guard in Puppet::Util::Package::Version::Gem.parse: it raises ValidationFailure with the generic message '#{version} is not a valid ruby gem version.' when the argument is not a String (version.is_a? String check at gem.rb:6). Note the class subclasses ::Gem::Version, but unlike Gem::Version.new it refuses non-String input outright instead of coercing or raising Gem::InvalidVersionError.

Source

Thrown at lib/puppet/util/package/version/gem.rb:6

# frozen_string_literal: true

module Puppet::Util::Package::Version
  class Gem < ::Gem::Version
    def self.parse(version)
      raise ValidationFailure, version unless version.is_a? String
      raise ValidationFailure, version unless version =~ ANCHORED_VERSION_PATTERN

      new(version)
    end

    class ValidationFailure < ArgumentError
      def initialize(version)
        super("#{version} is not a valid ruby gem version.")
      end
    end
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Coerce before parsing: pass version.to_s if the value may be a Symbol or Integer.
  2. Guard with a type check: only call parse when value.is_a?(String).
  3. Pre-validate with Gem::Version.correct?(value.to_s) and only construct when true.
  4. Rescue Puppet::Util::Package::Version::Gem::ValidationFailure (ArgumentError subclass) around the call.

Example fix

// before
v = Puppet::Util::Package::Version::Gem.parse(manifest_value) # manifest_value = :'2.1.0'

// after
v = if manifest_value.is_a?(String)
      Puppet::Util::Package::Version::Gem.parse(manifest_value)
    elsif Gem::Version.correct?(manifest_value.to_s)
      Puppet::Util::Package::Version::Gem.parse(manifest_value.to_s)
    end
Defensive patterns

Strategy: type-guard

Validate before calling

raw = candidate.is_a?(String) ? candidate : candidate.to_s
ok = Gem::Version.correct?(raw)

Type guard

def gem_version_input?(value)
  value.is_a?(String) && Gem::Version.correct?(value)
end

Try / catch

begin
  Puppet::Util::Package::Version::Gem.parse(raw)
rescue Puppet::Util::Package::Version::Gem::ValidationFailure
  nil # treat as unparseable, keep manifest version as plain string
end

Prevention

When it happens

Trigger: Gem.parse(nil), Gem.parse(:'1.0.0') (symbol from a Puppet manifest value), Gem.parse(1.0) or Gem.parse(2) (numeric from JSON), Gem.parse(Gem::Version.new('1.0')) (double-parsing an already parsed version object).

Common situations: Version values coming from YAML/JSON/Hiera that deserialize as numbers or symbols; helper code that stores parsed versions and later re-parses them; defaults of nil passed through when a key is absent.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/6ca0a31b2314e801. Report an issue: GitHub.