puppetlabs/puppet · error · Puppet::ModuleTool::Errors::MultipleInstalledError

Could not %{action} '%{module_name}'; module appears in mult

Error message

Could not %{action} '%{module_name}'; module appears in multiple places in the module path

What it means

Uninstaller raises Puppet::ModuleTool::MultipleInstalledError when more than one module matching the requested name is found across the modulepath entries. Uninstalling would be ambiguous (which copy?), so the error lists every installed_modules entry sorted by modulepath order. Note the version filter first narrows @installed when --version is passed.

Source

Thrown at lib/puppet/module_tool/applications/uninstaller.rb:71

        @environment.modules_by_path.values.flatten.each do |mod|
          mod_name = (mod.forge_name || mod.name).tr('/', '-')
          if mod_name == @name
            @unfiltered << {
              :name => mod_name,
              :version => mod.version,
              :path => mod.modulepath,
            }
            if @options[:version] && mod.version
              next unless Puppet::Module.parse_range(@options[:version]).include?(SemanticPuppet::Version.parse(mod.version))
            end
            @installed << mod
          elsif mod_name =~ /#{@name}/
            @suggestions << mod_name
          end
        end

        if @installed.length > 1
          raise MultipleInstalledError,
                :action => :uninstall,
                :module_name => @name,
                :installed_modules => @installed.sort_by { |mod| @environment.modulepath.index(mod.modulepath) }
        elsif @installed.empty?
          if @unfiltered.empty?
            raise NotInstalledError,
                  :action => :uninstall,
                  :suggestions => @suggestions,
                  :module_name => @name
          else
            raise NoVersionMatchesError,
                  :installed_modules => @unfiltered.sort_by { |mod| @environment.modulepath.index(mod[:path]) },
                  :version_range => @options[:version],
                  :module_name => @name
          end
        end
      end

View on GitHub (pinned to e227c27540)

Solutions

  1. Disambiguate with the --version flag if the copies differ in version (the version filter runs before the multiplicity check).
  2. Remove the duplicate copy from one modulepath directory (keep the one in the intended scope), then re-run uninstall.
  3. Use the full environment/modulepath layout to confirm where each copy lives: `puppet module list --modulepath <dir>` for each entry.

Example fix

# before
puppet module uninstall stdlib   # two copies: env modules + global modules

# after
rm -rf /etc/puppetlabs/code/modules/stdlib   # remove the stray copy
puppet module uninstall stdlib
Defensive patterns

Strategy: validation

Validate before calling

matches = Puppet.settings[:modulepath].split(File::PATH_SEPARATOR).flat_map do |dir|
  Dir.glob(File.join(dir, @name)).select { |d| File.directory?(d) }
end
abort 'module appears in multiple modulepath entries' if matches.size > 1

Try / catch

begin
  uninstaller.run
rescue Puppet::ModuleTool::MultipleInstalledError => e
  mods = e.multiline_options[:installed_modules]
  choose_and_narrow(mods) # e.g. add --version to disambiguate
end

Prevention

When it happens

Trigger: Running `puppet module uninstall stdlib` when both /etc/puppetlabs/code/environments/prod/modules/stdlib and /etc/puppetlabs/code/modules/stdlib exist; the same module copied into an environment and the global modules directory; basemodulepath copies. @installed.length > 1 triggers it.

Common situations: Environments inheriting modules duplicated in the global modulepath; manually copied modules during debugging; distro packages installing modules system-wide that also exist per-environment.

Related errors


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