puppetlabs/puppet · error · ArgumentError
Data Type Load Error for type '%{type_name}': %{message}
Error message
Data Type Load Error for type '%{type_name}': %{message} What it means
Puppet::DataTypes.create_type wraps the entire Ruby data-type definition block: any StandardError raised while building the type (unparsable interface string, duplicate interface/implementation declarations, NameError inside the implementation, load_file of a missing file) is re-raised as ArgumentError 'Data Type Load Error for type X: <original message>'. The text after the colon is the underlying exception and identifies the true fault.
Source
Thrown at lib/puppet/datatypes.rb:135
#
# # This load_file is optional and only needed in case
# # the implementation is not loaded by other means.
# load_file 'puppetx/auth/user'
#
# implementation_class PuppetX::Auth::User
# end
#
module Puppet::DataTypes
def self.create_type(type_name, &block)
# Ruby < 2.1.0 does not have method on Binding, can only do eval
# and it will fail unless protected with an if defined? if the local
# variable does not exist in the block's binder.
#
loader = block.binding.eval('loader_injected_arg if defined?(loader_injected_arg)')
create_loaded_type(type_name, loader, &block)
rescue StandardError => e
raise ArgumentError, _("Data Type Load Error for type '%{type_name}': %{message}") % { type_name: type_name, message: e.message }
end
def self.create_loaded_type(type_name, loader, &block)
builder = TypeBuilder.new(type_name.to_s)
api = TypeBuilderAPI.new(builder).freeze
api.instance_eval(&block)
builder.create_type(loader)
end
# @api private
class TypeBuilder
attr_accessor :interface, :implementation, :implementation_class
def initialize(type_name)
@type_name = type_name
@implementation = nil
@implementation_class = nil
endView on GitHub (pinned to e227c27540)
Solutions
- Read the message after 'Data Type Load Error for type X: ' — it is the root-cause exception text; fix that first
- Sanity-check the interface string by parsing it: Puppet::Pops::Parser::EvaluatingParser.new.parse_string("{ #{iface} }")
- Reproduce in isolation: place the type in a scratch module and run `puppet apply -e 'notice(My::Type)'`
Example fix
# before
Puppet::DataTypes.create_type('Bad') { interface 'attributes => {' } # unbalanced braces
# after
Puppet::DataTypes.create_type('Good') { interface 'attributes => { value => String }' } Defensive patterns
Strategy: try-catch
Validate before calling
# fail fast with a clean message while loading type files
begin
Puppet::DataTypes.create_type(name, &block)
rescue ArgumentError => e
raise unless e.message =~ /Data Type Load Error/
raise "#{name}: #{e.message}"
end Try / catch
begin
Puppet::DataTypes.create_type('My::Type', &block)
rescue ArgumentError => e
if e.message.start_with?('Data Type Load Error')
# the suffix is the original exception's message — log it, fix the type definition
Puppet.err e.message
else
raise
end
end Prevention
- Parse-check interface strings with EvaluatingParser during development
- Load each new data type in isolation (`puppet apply -e 'notice(My::Type)'`) before shipping
When it happens
Trigger: Authoring Puppet::DataTypes.create_type('My::Type') { ... } in lib/puppet/datatypes with an interface string that fails to parse; declaring interface or implementation twice; the implementation block referencing an undefined constant; load_file pointing at a nonexistent file.
Common situations: First drafts of Ruby data types in a module; refactors that break the interface string; Puppet upgrades that made the parser stricter.
Related errors
- a data type must have an interface
- a data type can only have one interface
- a data type can only have one implementation
- #{subject} #{what},
- title patterns that use procs are not supported.
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/4f523e226b9c9383.
Report an issue: GitHub.