puppetlabs/puppet · error · ArgumentError
Invalid 'version_range' field in metadata.json: %{err}
Error message
Invalid 'version_range' field in metadata.json: %{err} What it means
Puppet::ModuleTool::Metadata#validate_version_range wraps SemanticPuppet::VersionRange.parse and converts its ArgumentError into this metadata-specific message. Every dependency's version_requirement in metadata.json passes through here (add_dependency line 69), so one malformed range anywhere in the dependency list fails the whole metadata parse with the underlying parse error shown.
Source
Thrown at lib/puppet/module_tool/metadata.rb:224
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")
end
end
# Validates that the version range can be parsed by Semantic.
def validate_version_range(version_range)
SemanticPuppet::VersionRange.parse(version_range)
rescue ArgumentError => e
raise ArgumentError, _("Invalid 'version_range' field in metadata.json: %{err}") % { err: e }
end
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Use SemanticPuppet range syntax: '>= 1.0.0 < 3.0.0', '1.x', or exact '2.1.3'
- Remove non-SemVer conventions: no '^', no '~>', no 'latest' in version_requirement
- Test the range standalone: `ruby -r semantic_puppet -e "SemanticPuppet::VersionRange.parse(ARGV[0])" '>= 1.0.0 < 2.0.0'`
- If you want 'any version', omit version_requirement entirely instead of using a placeholder string
Example fix
// before - metadata.json
{ "name": "puppetlabs/stdlib", "version_requirement": "^4.0.0" }
// after
{ "name": "puppetlabs/stdlib", "version_requirement": ">= 4.0.0 < 5.0.0" } Defensive patterns
Strategy: validation
Validate before calling
require 'semantic_puppet'
JSON.parse(File.read('metadata.json'))['dependencies'].each do |dep|
next unless dep['version_requirement']
begin
SemanticPuppet::VersionRange.parse(dep['version_requirement'])
rescue ArgumentError
abort "dependency #{dep['name']} has unparseable range '#{dep['version_requirement']}'"
end
end Try / catch
begin metadata.add_dependency(dep['name'], dep['version_requirement']) rescue ArgumentError => e raise unless e.message =~ /Invalid 'version_range' field/ normalized = dep['version_requirement'].gsub(/\^|~>/, '').strip # drop gem/npm-style operators metadata.add_dependency(dep['name'], normalized.empty? ? nil : normalized) end
Prevention
- Use only SemanticPuppet range syntax ('>= 1.0.0 < 2.0.0', '1.x', exact versions) in version_requirement
- Omit version_requirement rather than writing 'latest' or placeholder strings
- Run metadata-json-lint in CI to validate every dependency range before release
When it happens
Trigger: A metadata.json dependency with "version_requirement": "latest", ">= 1.0 < < 2.0" (malformed operator), "1.x.x.x" or another string SemanticPuppet::VersionRange.parse rejects; parse error text is embedded via %{err}.
Common situations: Copy-pasting npm/gem style ranges ('^1.2.3', '~> 2.1') that SemanticPuppet does not accept; typo'd operators; empty-string requirements after bad templating; ranges assembled by string concatenation that drop a bound.
Related errors
- Invalid 'version' field in metadata.json: %{err}
- Dependency conflict for %{module_name}: Dependency %{name} w
- Invalid 'name' field in metadata.json: %{err}
- field 'data_provider' contains non-alphanumeric characters
- field 'data_provider' must begin with a letter
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/89b22383e17a7397.
Report an issue: GitHub.