puppetlabs/puppet · error · ArgumentError

Unable to find metadata.json in module root at %{path} See h

Error message

Unable to find metadata.json in module root at %{path} See https://puppet.com/docs/puppet/latest/modules_publishing.html for required file format.

What it means

Application#metadata raises ArgumentError when require_metadata is true and Puppet::ModuleTool.is_module_root?(@path) is false — the directory does not contain a metadata.json at its root. Operations that fundamentally need module metadata (build, change-owner, unpack of an existing module) pass require_metadata = true (via load_metadata!), so a directory lacking metadata.json is rejected.

Source

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

            Puppet::Util::Json.load(response.body)['error']
          rescue
            "HTTP #{response.code}, #{response.body}"
          end
          Puppet.warning "#{failure} (#{errors})"
        end
      end

      def metadata(require_metadata = false)
        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

View on GitHub (pinned to e227c27540)

Solutions

  1. Run the command from the module's root directory — the one that should contain metadata.json.
  2. Create a metadata.json with name, version, author, license, summary, source, dependencies (use `puppet module generate` as a template).
  3. If metadata.json was renamed/removed, restore it from version control.
  4. Remove the obsolete Modulefile if present (it is ignored and warned about).

Example fix

# before: module dir has only Modulefile

# after: module root contains metadata.json
{
  "name": "acme-webservice",
  "version": "0.1.0",
  "author": "acme",
  "license": "Apache-2.0",
  "summary": "Web service module",
  "source": "https://github.com/acme/puppet-webservice",
  "dependencies": []
}
Defensive patterns

Strategy: validation

Validate before calling

require 'puppet/module_tool'

abort 'not a module root: metadata.json missing' unless Puppet::ModuleTool.is_module_root?(path)

Type guard

def module_root?(path)
  File.file?(File.join(path.to_s, 'metadata.json'))
end

Try / catch

begin
  app = Puppet::ModuleTool::Applications::Builder.new(path)
  app.run
rescue ArgumentError => e
  raise unless e.message.include?('Unable to find metadata.json')
  abort "#{path} is not a module root - create metadata.json first"
end

Prevention

When it happens

Trigger: Running `puppet module build` (or the Builder application) in a directory without metadata.json; passing a subdirectory of the module (manifests/, examples/) instead of the root; a module created from a bare skeleton that never got metadata.json.

Common situations: Old modules migrated from Modulefile-era layout that never got converted to metadata.json; running tooling from the wrong cwd; metadata.json accidentally renamed or gitignored; typos like metadata.json.bak.

Related errors


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