puppetlabs/puppet · error · ArgumentError

Could not determine module path

Error message

Could not determine module path

What it means

ModuleTool::Applications::Application#metadata raises ArgumentError('Could not determine module path') when @path is nil at the time metadata is loaded. The application base class (Installer, Uninstaller, Builder, etc.) expects the target module path to be set during initialization; a nil path means the constructor was given no resolvable directory (e.g. nil/empty name and no explicit path).

Source

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

        when Net::HTTPOK, Net::HTTPCreated
          Puppet.notice success
        else
          errors = begin
            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.")

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass an explicit directory: run the command from the module root, or supply the path option (e.g. `puppet module build /path/to/module`).
  2. If calling the API, ensure options include a resolvable target so @path is set before #run.
  3. Check for typos in the path argument that make it non-existent and leave @path unset.

Example fix

# before
Puppet::ModuleTool::Applications::Installer.new(nil, :install_dir => dir).run

# after
Puppet::ModuleTool::Applications::Installer.new('puppetlabs-stdlib', :install_dir => dir).run
Defensive patterns

Strategy: validation

Validate before calling

abort 'no module path: run from module root or pass --path/PATH' unless options[:install_dir] || Dir.pwd

Try / catch

begin
  app.run
rescue ArgumentError => e
  raise if e.message != 'Could not determine module path'
  abort 'run this command from the module root or specify the target path'
end

Prevention

When it happens

Trigger: Instantiating Puppet::ModuleTool::Applications::Installer or similar with options where neither a module name resolving to a directory nor an explicit :install_dir/:path produces a value, then calling #metadata or #run, which calls metadata and hits the `unless @path` branch.

Common situations: Programmatic use of the module_tool applications with missing options hash keys; a Rake task or wrapper that passes nil for the module directory; running from a cwd outside any module without --path so path derivation returns nil.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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