puppetlabs/puppet · error · ArgumentError

Invalid 'version' field in metadata.json: %{err}

Error message

Invalid 'version' field in metadata.json: %{err}

What it means

Puppet::ModuleTool::Metadata#validate_version rejects any 'version' string that SemanticPuppet::Version.valid? cannot parse as strict SemVer. The field must be exactly MAJOR.MINOR.PATCH (with optional pre-release/build), so two-segment versions, leading 'v', or 'latest' all fail when the metadata.json is parsed (line 135).

Source

Thrown at lib/puppet/module_tool/metadata.rb:198

            when nil, '', :namespace_missing
              _("the field must be a namespaced module name")
            when /[^a-z0-9_]/i
              _("the module name contains non-alphanumeric (or underscore) characters")
            when /^[^a-z]/i
              _("the module name must begin with a letter")
            else
              _("the namespace contains non-alphanumeric characters")
            end

      raise ArgumentError, _("Invalid 'name' field in metadata.json: %{err}") % { err: err }
    end

    # Validates that the version string can be parsed as per SemVer.
    def validate_version(version)
      return if SemanticPuppet::Version.valid?(version)

      err = _("version string cannot be parsed as a valid Semantic Version")
      raise ArgumentError, _("Invalid 'version' field in metadata.json: %{err}") % { err: err }
    end

    # Validates that the given _value_ is a symbolic name that starts with a letter
    # and then contains only letters, digits, or underscore. Will raise an ArgumentError
    # if that's not the case.
    #
    # @param value [Object] The value to be tested
    def validate_data_provider(value)
      if value.is_a?(String)
        unless value =~ /^[a-zA-Z][a-zA-Z0-9_]*$/
          if value =~ /^[a-zA-Z]/
            raise ArgumentError, _("field 'data_provider' contains non-alphanumeric characters")
          else
            raise ArgumentError, _("field 'data_provider' must begin with a letter")
          end
        end
      else
        raise ArgumentError, _("field 'data_provider' must be a string")

View on GitHub (pinned to e227c27540)

Solutions

  1. Use full three-segment SemVer: "version": "1.2.3"
  2. Drop prefixes: 'v1.2.3' → '1.2.3'
  3. Put pre-release/build metadata in proper SemVer form: '1.2.3-beta.1' / '1.2.3+build.4'
  4. Regenerate metadata with `puppet module generate` to confirm the accepted shape

Example fix

// before - metadata.json
"version": "v1.2",

// after
"version": "1.2.0",
Defensive patterns

Strategy: validation

Validate before calling

require 'semantic_puppet'

version = JSON.parse(File.read('metadata.json'))['version']
abort "version '#{version}' is not valid SemVer (MAJOR.MINOR.PATCH)" unless SemanticPuppet::Version.valid?(version)

Try / catch

begin
  Puppet::ModuleTool::Metadata.from_hash('name' => 'acme-foo', 'version' => raw)
rescue ArgumentError => e
  raise unless e.message =~ /Invalid 'version' field/
  raw = normalize_to_semver(raw)  # e.g. 'v1.2' -> '1.2.0'
  retry
end

Prevention

When it happens

Trigger: A metadata.json with "version": "1.0" (two segments), "2.0.0.0" (four segments), "v1.2.3" (v prefix), "latest", or "1.2.3-beta" written with an invalid pre-release identifier such as '01'.

Common situations: Authors used to Gemfile-style '~> 1.0' or npm-style '^1.2.3' conventions; automation stamping dates or build numbers like '2023.04' into version; missing patch segment when hand-editing.

Related errors


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