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

puppet.tasks/no-implementation

puppet.tasks/no-implementation

Error message

No source besides task metadata was found in directory %{directory} for task %{name}

What it means

Raised as Puppet::Error when a device.conf line matches none of the accepted forms: comment, blank, `[device.name]` header, or a `type|url|debug <value>` directive. The offending line's text is included verbatim in %{file_text} with its location, so the message is self-describing. It fires during config parsing for `puppet device`.

Source

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

            raise InvalidMetadata.new(msg, 'puppet.tasks/invalid-metadata')
          end
          path = executables.find { |real_impl| File.basename(real_impl) == impl['name'] }
          unless path
            msg = _("Task metadata for task %{name} specifies missing implementation %{implementation}" % { name: name, implementation: impl['name'] })
            raise InvalidTask.new(msg, 'puppet.tasks/missing-implementation', { missing: [impl['name']] })
          end
          { "name" => impl['name'], "path" => path }
        end
        return implementations
      end

      # If implementations isn't defined, then we use executables matching the
      # task name, and only one may exist.
      implementations = executables.select { |impl| File.basename(impl, '.*') == basename }
      if implementations.empty?
        msg = _('No source besides task metadata was found in directory %{directory} for task %{name}') %
              { name: name, directory: directory }
        raise InvalidTask.new(msg, 'puppet.tasks/no-implementation')
      elsif implementations.length > 1
        msg = _("Multiple executables were found in directory %{directory} for task %{name}; define 'implementations' in metadata to differentiate between them") %
              { name: name, directory: implementations[0] }
        raise InvalidTask.new(msg, 'puppet.tasks/multiple-implementations')
      end

      [{ "name" => File.basename(implementations.first), "path" => implementations.first }]
    end
    private_class_method :find_implementations

    def self.find_files(name, directory, metadata, executables, envname = nil)
      # PXP agent relies on 'impls' (which is the task file) being first if there is no metadata
      find_implementations(name, directory, metadata, executables) + find_extra_files(metadata, envname)
    end

    def self.is_tasks_metadata_filename?(name)
      is_tasks_filename?(name) && name.end_with?('.json')
    end

View on GitHub (pinned to e227c27540)

Solutions

  1. Go to the line named in %{error_location} and either fix it to `type|url|debug <value>` form, comment it with #, or delete it
  2. Ensure section headers only contain word/dot/dash characters: [router-01.example.com]
  3. Normalize line endings to LF if the file was edited on Windows
  4. Re-run `puppet device --verbose` after each fix to confirm parsing passes

Example fix

# before
[sw01.example.com]
type cisco
url ssh://admin:pass@sw01.example.com
user admin            # unsupported directive -> Invalid entry

# after
[sw01.example.com]
type cisco
url ssh://admin:pass@sw01.example.com
# credentials belong in the url, not a 'user' line
Defensive patterns

Strategy: validation

Validate before calling

VALID = /^\s*(#.*|\[\w[\w.-]*\]\s*|(type|url|debug)\s+.+\s*)$/
File.readlines('device.conf', chomp: true).each_with_index do |l, i|
  raise "bad device.conf line #{i + 1}: #{l}" unless l =~ VALID
end

Try / catch

begin
  config.read
rescue Puppet::Error => e
  raise unless e.message =~ /Invalid entry/
  # %{file_text} shows the exact offending line; fix it and retry the device run
  raise
end

Prevention

When it happens

Trigger: A stray line in device.conf: a misspelled directive (`username = ...`, `timeout 30`), a value-only line, a continuation/indent leftover, section headers with invalid characters (the header regex requires [\w.-]+), or Windows line endings making otherwise-valid lines unmatched.

Common situations: Hand edits adding unsupported keys; templating that injects comments without '#'; CRLF from editing on Windows; examples copied from docs that use unsupported directives like `user`.

Related errors


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