puppetlabs/puppet · error · Puppet::DevError
No command %{command} defined for provider %{provider}
Error message
No command %{command} defined for provider %{provider} What it means
Providers declare external commands with commands :name => 'executable'; declarations live in a per-class @commands hash consulted with superclass lookup. Provider.command(name) returns the absolute path found via which(), and raises Puppet::DevError 'No command X defined for provider Y' when the name was never declared. This is a typo or missing declaration, distinct from a declared executable not being found on disk, which fails later in which().
Source
Thrown at lib/puppet/provider.rb:134
# (see Puppet::Util::Execution.execpipe)
def self.execpipe(*args, &block)
Puppet::Util::Execution.execpipe(*args, &block)
end
# Returns the absolute path to the executable for the command referenced by the given name.
# @raise [Puppet::DevError] if the name does not reference an existing command.
# @return [String] the absolute path to the found executable for the command
# @see which
# @api public
def self.command(name)
name = name.intern
command = @commands[name] if defined?(@commands)
command = superclass.command(name) if !command && superclass.respond_to?(:command)
unless command
raise Puppet::DevError, _("No command %{command} defined for provider %{provider}") % { command: name, provider: self.name }
end
which(command)
end
# Confines this provider to be suitable only on hosts where the given commands are present.
# Also see {Puppet::Confiner#confine} for other types of confinement of a provider by use of other types of
# predicates.
#
# @note It is preferred if the commands are not entered with absolute paths as this allows puppet
# to search for them using the PATH variable.
#
# @param command_specs [Hash{String => String}] Map of name to command that the provider will
# be executing on the system. Each command is specified with a name and the path of the executable.
# @return [void]
# @see optional_commands
# @api public
#View on GitHub (pinned to e227c27540)
Solutions
- Add the declaration at the top of the provider class: commands :list => 'lslv'.
- Fix the symbol passed to command() so it matches the declaration exactly.
- For shared command sets, declare them in a base provider class that both providers inherit from.
Example fix
# before (provider) def self.instances cmd = command(:list) # Puppet::DevError: No command list defined end # after commands :list => 'lslv' def self.instances cmd = command(:list) end
Defensive patterns
Strategy: try-catch
Validate before calling
declared = {}
klass = provider.class
while klass && klass < Puppet::Provider
declared.merge!(klass.instance_variable_get(:@commands) || {})
klass = klass.superclass
end
fail 'undeclared command :list' unless declared.key?(:list) Type guard
def declared_command?(provider_class, name)
k = provider_class
while k
return true if (k.instance_variable_get(:@commands) || {}).key?(name)
k = k.superclass
end
false
end Try / catch
begin
executable = self.class.command(:list)
rescue Puppet::DevError => e
raise Puppet::Error, "#{self.class.name}: #{e.message} (declare with commands :list => 'lslv')"
end Prevention
- Declare every command the provider uses with commands :name => 'exe' before referencing it.
- Unit-test providers with a stub for command() so undeclared names surface early.
- Keep declaration and call sites spelled identically (symbols, not strings).
When it happens
Trigger: A provider method calls command(:list) but the class declares commands :lslv => 'lslv'; the symbol is misspelled on either side; the declaration exists on a sibling provider class instead of this class or an ancestor.
Common situations: Custom provider development; refactors that rename command aliases; copy-paste between providers where declarations were left behind.
Related errors
- To support listing resources of this type the '%{provider}'
- Unable to verify the SSL certificate at %{uri}
- Provider %{provider} must have features '%{needed_feature}'
- No ability to determine if %{name} exists
- Could not set %{property} on %{resource}[%{name}]: %{detail}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/6049f49329f85862.
Report an issue: GitHub.