puppetlabs/puppet · error · Serialization::SerializationError
Initializer for class #{impl_class.name} does not match the
Error message
Initializer for class #{impl_class.name} does not match the attributes of #{name} What it means
When Puppet instantiates or pcore-deserializes an Object type with a Ruby implementation class, parameter_info compares the parameters of the impl class's initialize method against the type's declared attributes. Serialization::SerializationError is raised when initialize accepts fewer parameters than there are attributes, or has more required parameters than attributes - meaning instances could not be constructed faithfully from their attribute values.
Source
Thrown at lib/puppet/pops/types/p_object_type.rb:648
param_types = non_opt_types + opt_types
param_count = param_names.size
init = impl_class.respond_to?(:from_asserted_args) ? impl_class.method(:from_asserted_args) : impl_class.instance_method(:initialize)
init_non_opt_count = 0
init_param_names = init.parameters.map do |p|
init_non_opt_count += 1 if :req == p[0]
n = p[1].to_s
r = RubyGenerator.unprotect_reserved_name(n)
unless r.equal?(n)
# assert that the protected name wasn't a real name (names can start with underscore)
n = r unless param_names.index(r).nil?
end
n
end
if init_param_names != param_names
if init_param_names.size < param_count || init_non_opt_count > param_count
raise Serialization::SerializationError, "Initializer for class #{impl_class.name} does not match the attributes of #{name}"
end
init_param_names = init_param_names[0, param_count] if init_param_names.size > param_count
unless init_param_names == param_names
# Reorder needed to match initialize method arguments
new_param_types = []
init_param_names.each do |ip|
index = param_names.index(ip)
if index.nil?
raise Serialization::SerializationError,
"Initializer for class #{impl_class.name} parameter '#{ip}' does not match any of the attributes of type #{name}"
end
new_param_types << param_types[index]
end
param_names = init_param_names
param_types = new_param_types
end
endView on GitHub (pinned to e227c27540)
Solutions
- Align the implementation class's initialize parameter list with the type's attributes: same names, and every attribute covered
- If initialize must accept extra arguments, make them optional (default values); required params may never exceed the attribute count
- Re-check after every change to the interface's attributes block - names must match exactly (a leading underscore is treated as name protection, not a distinct name)
Example fix
# before
Puppet::DataTypes.create_type('MyApp::Point') do
interface <<-PUPPET
attributes => { x => Integer, y => Integer, z => Integer }
PUPPET
implementation_class Class.new do
def initialize(x, y) # z is not covered
@x, @y = x, y
end
end
end
# after
implementation_class Class.new do
def initialize(x, y, z) # covers all three attributes
@x, @y, @z = x, y, z
end
end Defensive patterns
Strategy: validation
Validate before calling
# before creating instances, compare initialize params with the type's attributes
params = impl_class.instance_method(:initialize).parameters
count = type.attributes(true).size
required = params.count { |kind, _| kind == :req }
names = params.map { |_, n| n.to_s.sub(/\A_/, '') }
abort 'initializer too small or too strict' if names.size < count || required > count
abort 'unknown initializer params: ' + (names - type.attributes(true).keys).inspect unless (names - type.attributes(true).keys).empty? Try / catch
begin
type.create(*args)
rescue Puppet::Pops::Serialization::SerializationError => e
raise unless e.message =~ /Initializer for class/
# re-raise with context: which type and which implementation class diverged
raise "#{type.name}: implementation class out of sync with attributes: #{e.message}"
end Prevention
- Treat the interface attributes block and the implementation initialize as one unit: change them in the same commit
- Cover data type instantiation with a unit test so the check fires at test time, not during a production catalog compile
- Prefer implementation blocks over custom initialize when possible; the generated initializer always matches
When it happens
Trigger: Creating an instance (or deserializing one) of a type whose implementation class defines initialize(x, y) while the interface declares three attributes (x, y, z), or initialize(a, b, c) with all three required while the type only declares two attributes. The check runs lazily, typically on first new() call or during pcore serialization.
Common situations: An attribute was added to the interface string but the Ruby implementation_class initialize was never updated; attributes were renamed or reordered without touching the implementation; copying an implementation class from a similar type with a different attribute set.
Related errors
- Initializer for class #{impl_class.name} parameter '#{ip}' d
- The attribute '%{name}' is reserved and cannot be used
- #{klass} does not respond to #{intern_multiple_method}; can
- #{instance.class} does not respond to #{render_method}; can
- %{klass} does not respond to %{method}; can not render multi
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/f7286f1a703a0116.
Report an issue: GitHub.