puppetlabs/puppet · error · Puppet::Module::Task::InvalidMetadata

puppet.task/invalid-metadata

puppet.task/invalid-metadata

Error message

Files specified in task metadata cannot include a trailing slash: %{file}

What it means

Raised as ArgumentError by Puppet::Util::Ldap::Manager#entry2provider when the entry hash passed in has no 'dn' key. The conversion immediately needs the distinguished name to derive the resource name (it pops the single dn value and strips it down to the rdn value), so an entry without dn cannot be converted at all. This is a contract violation between the LDAP search layer and the manager, not an I/O failure.

Source

Thrown at lib/puppet/module/task.rb:147

        end

        unless File.exist?(path)
          msg = _("Could not find %{path} on disk" % { path: path })
          raise InvalidFile, msg
        end

        last_char = file[-1] == '/'
        if File.directory?(path)
          unless last_char
            msg = _("Directories specified in task metadata must include a trailing slash: %{dir}" % { dir: file })
            raise InvalidMetadata.new(msg, 'puppet.tasks/invalid-metadata')
          end
          dir_files = Dir.glob("#{path}**/*").select { |f| File.file?(f) }
          dir_files.map { |f| get_file_details(f, pup_module) }
        else
          if last_char
            msg = _("Files specified in task metadata cannot include a trailing slash: %{file}" % { file: file })
            raise InvalidMetadata.new(msg, 'puppet.task/invalid-metadata')
          end
          get_file_details(path, pup_module)
        end
      end
    end
    private_class_method :find_extra_files

    # Executables list should contain the full path of all possible implementation files
    def self.find_implementations(name, directory, metadata, executables)
      basename = name.split('::')[1] || 'init'
      # If 'implementations' is defined, it needs to mention at least one
      # implementation, and everything it mentions must exist.
      metadata ||= {}
      if metadata.key?('implementations')
        unless metadata['implementations'].is_a?(Array)
          msg = _("Task metadata for task %{name} does not specify implementations as an array" % { name: name })
          raise InvalidMetadata.new(msg, 'puppet.tasks/invalid-metadata')
        end

View on GitHub (pinned to e227c27540)

Solutions

  1. Ensure the search requests the dn (or that the client keeps it in the attribute hash) before calling entry2provider
  2. Fix fixture/spec hashes to include 'dn' => ['cn=name,ou=...,dc=...']
  3. Guard at the call site: skip or log entries lacking 'dn' instead of passing them through

Example fix

# before
entry = { 'cn' => ['web01'], 'objectclass' => ['top'] }
manager.entry2provider(entry) # raises ArgumentError

# after
entry = { 'dn' => ['cn=web01,ou=hosts,dc=example,dc=com'], 'cn' => ['web01'], 'objectclass' => ['top'] }
manager.entry2provider(entry)
Defensive patterns

Strategy: type-guard

Type guard

def convertible_entry?(entry)
  entry.is_a?(Hash) && entry['dn'].is_a?(Array) && !entry['dn'].empty?
end

results.select { |e| convertible_entry?(e) }.each { |e| manager.entry2provider(e) }

Try / catch

begin
  manager.entry2provider(entry)
rescue ArgumentError => e
  raise unless e.message =~ /Could not get dn/
  Puppet.debug("skipping LDAP entry without dn: #{entry.inspect}")
end

Prevention

When it happens

Trigger: Calling manager.entry2provider(entry) with a hash built by hand or by a search whose attribute list excludes dn; tests with fixture entries that omit 'dn'; custom code reusing the manager on entries obtained from a different LDAP client that returns dn separately from attributes.

Common situations: rspec fixtures copied from ldapsearch output without the dn: line; code paths that filter search results and accidentally drop the dn pair; upgrades of client libraries that stop merging dn into the attribute hash.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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