puppetlabs/puppet · error · ArgumentError

The code loaded from %{source_ref} produced type with the wr

Error message

The code loaded from %{source_ref} produced type with the wrong name, expected '%{name}', actual '%{actual_name}'

What it means

TypeDefinitionInstantiator.create compares the type name the loader expects (typed_name.name, already lowercase, e.g. 'mymodule::mytype') against type_definition.name.downcase. If the defined name differs — even by one segment — this ArgumentError reports both names. Puppet type files must define exactly the type they are named after, case-insensitively, so types/MyType.pp must define mymodule::MyType (any casing), not some other name.

Source

Thrown at lib/puppet/pops/loader/type_definition_instantiator.rb:33

    case model.definitions.size
    when 0
      raise ArgumentError, _("The code loaded from %{source_ref} does not define the type '%{name}' - it is empty.") % { source_ref: source_ref, name: name }
    when 1
      # ok
    else
      raise ArgumentError,
            _("The code loaded from %{source_ref} must contain only the type '%{name}' - it has additional definitions.") % { source_ref: source_ref, name: name }
    end
    type_definition = model.definitions[0]

    unless type_definition.is_a?(Model::TypeAlias) || type_definition.is_a?(Model::TypeDefinition)
      raise ArgumentError,
            _("The code loaded from %{source_ref} does not define the type '%{name}' - no type alias or type definition found.") % { source_ref: source_ref, name: name }
    end

    actual_name = type_definition.name
    unless name == actual_name.downcase
      raise ArgumentError,
            _("The code loaded from %{source_ref} produced type with the wrong name, expected '%{name}', actual '%{actual_name}'") % { source_ref: source_ref, name: name, actual_name: actual_name }
    end

    unless model.body == type_definition
      raise ArgumentError,
            _("The code loaded from %{source_ref} contains additional logic - can only contain the type '%{name}'") % { source_ref: source_ref, name: name }
    end

    # Adapt the type definition with loader - this is used from logic contained in its body to find the
    # loader to use when resolving contained aliases API. Such logic have a hard time finding the closure (where
    # the loader is known - hence this mechanism
    private_loader = loader.private_loader
    Adapters::LoaderAdapter.adapt(type_definition).loader_name = private_loader.loader_name
    create_runtime_type(type_definition)
  end

  def self.create_from_model(type_definition, loader)
    typed_name = TypedName.new(:type, type_definition.name)

View on GitHub (pinned to e227c27540)

Solutions

  1. Make the name inside the file match the file path: file types/<name>.pp must declare `type <module>::<name>`.
  2. If you renamed the type, rename the file to match the new name and update references.
  3. Delete duplicated files that declare a type belonging to another filename.

Example fix

// before: modules/mymodule/types/mytype.pp
type mymodule::othertype = String

// after: modules/mymodule/types/mytype.pp
type mymodule::mytype = String
Defensive patterns

Strategy: validation

Validate before calling

# CI check: declared type name matches file path
require 'puppet'
require 'puppet/pops'

Dir['modules/*/types/**/*.pp'].each do |f|
  module_name = f.split('/')[1]
  expected = File.basename(f, '.pp')
  model = Puppet::Pops::Parser::EvaluatingParser.new.parse_string(File.read(f), f)
  actual = model.definitions[0]&.name.to_s
  ok = actual.downcase == "#{module_name}::#{expected}".downcase
  abort "#{f}: declares #{actual}, expected #{module_name}::#{expected}" unless ok
end

Prevention

When it happens

Trigger: types/mytype.pp that declares `type mymodule::othertype = String`; copy-pasting a type file and editing the body but not the name; renaming a type in code without renaming/rewriting the file; module rename leaving old type names inside files.

Common situations: Module renamed but types/ contents not updated; refactoring aliases and forgetting one file; casing is fine (downcase comparison) but segment spelling is not.

Related errors


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