puppetlabs/puppet · error · Puppet::Error
Unable to create an instance of #{name}. #{class_name} does
Error message
Unable to create an instance of #{name}. #{class_name} does not include module #{PuppetObject.name} What it means
A loaded implementation class for an Object type must either include Puppet::Pops::Types::PuppetObject (so instances support _pcore_type and PCore construction) or be an RGen metamodel class (responds to :ecore). If ClassLoader returns a class satisfying neither, Puppet::Error explains that the class does not include the PuppetObject module.
Source
Thrown at lib/puppet/pops/types/p_object_type.rb:565
end
end
# @api private
def implementation_class(create = true)
if @implementation_class.nil? && create
ir = Loaders.implementation_registry
class_name = ir.nil? ? nil : ir.module_name_for_type(self)
if class_name.nil?
# Use generator to create a default implementation
@implementation_class = RubyGenerator.new.create_class(self)
@implementation_class.class_eval(&@implementation_override) if instance_variable_defined?(:@implementation_override)
else
# Can the mapping be loaded?
@implementation_class = ClassLoader.provide(class_name)
raise Puppet::Error, "Unable to load class #{class_name}" if @implementation_class.nil?
unless @implementation_class < PuppetObject || @implementation_class.respond_to?(:ecore)
raise Puppet::Error, "Unable to create an instance of #{name}. #{class_name} does not include module #{PuppetObject.name}"
end
end
end
@implementation_class
end
# @api private
def implementation_class=(cls)
raise ArgumentError, "attempt to redefine implementation class for #{label}" unless @implementation_class.nil?
@implementation_class = cls
end
# The block passed to this method will be passed in a call to `#class_eval` on the dynamically generated
# class for this data type. It's indended use is to complement or redefine the generated methods and
# attribute readers.
#
# The method is normally called with the block passed to `#implementation` when a data type is defined usingView on GitHub (pinned to e227c27540)
Solutions
- In your implementation class, include Puppet::Pops::Types::PuppetObject (implementing _pcore_type / the standard constructor pattern, easiest via Puppet::DataTypes.create_type with an implementation block).
- If the class is an RGen/Ecore model class, respond to :ecore — that path is also accepted.
- Check the mapped name for collisions: ensure the registry entry points at the class you think it does (confirm with ClassLoader.provide in a Ruby shell).
Example fix
# before class PuppetX::Mymod::Widget attr_reader :size end # after require 'puppet/pops/types/puppet_object' class PuppetX::Mymod::Widget include Puppet::Pops::Types::PuppetObject attr_reader :size end
Defensive patterns
Strategy: type-guard
Validate before calling
# Ruby — verify the contract after loading the mapped class
klass = Puppet::Pops::Types::ClassLoader.provide(class_name)
unless klass.nil? || (klass < Puppet::Pops::Types::PuppetObject || klass.respond_to?(:ecore))
fail("#{class_name} must include PuppetObject or be an RGen (ecore) class")
end Type guard
def puppet_object_class?(klass) klass < Puppet::Pops::Types::PuppetObject || klass.respond_to?(:ecore) end
Try / catch
begin
obj_type.implementation_class
rescue Puppet::Error => e
raise TypeError, "#{e.message} — include Puppet::Pops::Types::PuppetObject in the mapped class"
end Prevention
- Base hand-written implementations on Puppet::DataTypes.create_type so the boilerplate is generated.
- Avoid mapping types to generic/toplevel constants; namespace implementation classes uniquely.
When it happens
Trigger: The registry mapping resolves to an existing Ruby class that is not a Puppet object implementation — e.g. a name collision where the mapped name resolves to a helper/stdlib class (::Set, ::Logger, a module of your own), or a hand-written implementation class created without including PuppetObject.
Common situations: Mapping a data type to an arbitrary domain class expecting Puppet to adapt it automatically; constant resolution picking up an unexpected toplevel constant of the same name; upgrading code where the implementation was replaced by a plain class.
Related errors
- Unable to load class #{class_name}
- attempt to redefine implementation class for #{label}
- Illegal format '#{actual}' specified for value of Object typ
- expected %{label} to override an inherited %{feature_type},
- %{member} attempts to override %{label}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/79b53eee25c70899.
Report an issue: GitHub.