puppetlabs/puppet · error · ArgumentError

The code loaded from %{source_ref} produced mis-matched name

Error message

The code loaded from %{source_ref} produced mis-matched name, expected '%{type_name}', got %{created_name}

What it means

Raised by RubyDataTypeInstantiator when the created data type's name does not match (case-insensitively, via casecmp) the typed name the loader requested. The name string given to Puppet::DataTypes.create_type must equal the name derived from the file name and module path.

Source

Thrown at lib/puppet/pops/loader/ruby_data_type_instantiator.rb:30

  # @param source_ref [URI, String] a reference to the source / origin of the ruby code to evaluate
  # @param ruby_code_string [String] ruby code in a string
  #
  # @return [Puppet::Pops::Types::PAnyType] - an instantiated data type associated with the given loader
  #
  def self.create(loader, typed_name, source_ref, ruby_code_string)
    unless ruby_code_string.is_a?(String) && ruby_code_string =~ /Puppet::DataTypes\.create_type/
      raise ArgumentError, _("The code loaded from %{source_ref} does not seem to be a Puppet 5x API data type - no create_type call.") % { source_ref: source_ref }
    end

    # make the private loader available in a binding to allow it to be passed on
    loader_for_type = loader.private_loader
    here = get_binding(loader_for_type)
    created = eval(ruby_code_string, here, source_ref, 1) # rubocop:disable Security/Eval
    unless created.is_a?(Puppet::Pops::Types::PAnyType)
      raise ArgumentError, _("The code loaded from %{source_ref} did not produce a data type when evaluated. Got '%{klass}'") % { source_ref: source_ref, klass: created.class }
    end
    unless created.name.casecmp(typed_name.name) == 0
      raise ArgumentError, _("The code loaded from %{source_ref} produced mis-matched name, expected '%{type_name}', got %{created_name}") % { source_ref: source_ref, type_name: typed_name.name, created_name: created.name }
    end

    created
  end

  # Produces a binding where the given loader is bound as a local variable (loader_injected_arg). This variable can be used in loaded
  # ruby code - e.g. to call Puppet::Function.create_loaded_function(:name, loader,...)
  #
  def self.get_binding(loader_injected_arg)
    binding
  end
  private_class_method :get_binding
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Set the create_type name to the exact namespaced name derived from module + file path
  2. Rename the file to match the create_type name if that is the desired name
  3. Note the comparison is case-insensitive, so a mismatch here means a real name difference, not casing

Example fix

# before - lib/puppet/datatypes/mymod/port.rb
Puppet::DataTypes.create_type('mymod::port_ssl') { ... }

# after
Puppet::DataTypes.create_type('mymod::port') { ... }
Defensive patterns

Strategy: try-catch

Try / catch

begin
  type = loader.load_typed(typed_name)
rescue ArgumentError => e
  raise unless e.message.include?('mis-matched name')
  warn "data type name mismatch: #{e.message}"
end

Prevention

When it happens

Trigger: `created.name.casecmp(typed_name.name) != 0`: e.g. create_type('mymod::port2') in a file loaded as mymod::port, or a missing module namespace segment.

Common situations: Renaming the file without updating the create_type name string (or vice versa); copy-paste; namespacing mistakes when moving types between modules.

Related errors


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