puppetlabs/puppet · error · ArgumentError

Could not parse JSON %{metadata_path}

Error message

Could not parse JSON %{metadata_path}

What it means

Application#metadata raises ArgumentError('Could not parse JSON <path>') when Puppet::Util::Json.load fails with Puppet::Util::Json::ParseError while reading the module's metadata.json. The file exists but is not valid JSON (or not UTF-8 clean), so its contents cannot be trusted for build/install decisions. The original backtrace is attached as the third raise argument.

Source

Thrown at lib/puppet/module_tool/applications/application.rb:59

        return @metadata if @metadata

        @metadata = Puppet::ModuleTool::Metadata.new

        unless @path
          raise ArgumentError, _("Could not determine module path")
        end

        if require_metadata && !Puppet::ModuleTool.is_module_root?(@path)
          raise ArgumentError, _("Unable to find metadata.json in module root at %{path} See https://puppet.com/docs/puppet/latest/modules_publishing.html for required file format.") % { path: @path }
        end

        metadata_path = File.join(@path, 'metadata.json')

        if File.file?(metadata_path)
          File.open(metadata_path) do |f|
            @metadata.update(Puppet::Util::Json.load(f))
          rescue Puppet::Util::Json::ParseError => ex
            raise ArgumentError, _("Could not parse JSON %{metadata_path}") % { metadata_path: metadata_path }, ex.backtrace
          end
        end

        if File.file?(File.join(@path, 'Modulefile'))
          Puppet.warning _("A Modulefile was found in the root directory of the module. This file will be ignored and can safely be removed.")
        end

        @metadata
      end

      def load_metadata!
        @metadata = nil
        metadata(true)
      end

      def parse_filename(filename)
        match = /^((.*?)-(.*?))-(\d+\.\d+\.\d+.*?)$/.match(File.basename(filename, '.tar.gz'))
        if match

View on GitHub (pinned to e227c27540)

Solutions

  1. Validate the file with a strict JSON parser: `ruby -rjson -e 'JSON.parse(File.read("metadata.json"))'` or `jq . metadata.json` to surface the exact line.
  2. Fix the reported syntax issue (remove trailing commas/comments, quote keys with double quotes, close braces).
  3. Remove git conflict markers after merges.
  4. Re-save the file as UTF-8 without BOM.

Example fix

// before
{
  'name': 'acme-web',  // single quotes and comment
  "version": "0.1.0",
}

// after
{
  "name": "acme-web",
  "version": "0.1.0"
}
Defensive patterns

Strategy: try-catch

Validate before calling

begin
  Puppet::Util::Json.load(File.read('metadata.json'))
rescue Puppet::Util::Json::ParseError => e
  abort "metadata.json is invalid: #{e.message}"
end

Try / catch

begin
  app.run
rescue ArgumentError => e
  if e.message.include?('Could not parse JSON')
    abort "fix metadata.json syntax: run `jq . metadata.json` to locate the error"
  end
  raise
end

Prevention

When it happens

Trigger: metadata.json containing trailing commas, single quotes, comments, unescaped newlines in strings, or a UTF-8 BOM; hand-edited JSON with a missing closing brace; a file written by a tool that emits YAML or pretty-print with smart quotes. Puppet::Util::Json (multijson-backed strict JSON) rejects it and the rescue clause re-raises as ArgumentError.

Common situations: Manually editing metadata.json and breaking syntax; merge-conflict markers left in the file from a git merge; encoding issues when editing on Windows (BOM, CRLF inside string literals); tools that write JSON5.

Related errors


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