puppetlabs/puppet · error · ArgumentError
The code loaded from %{source_ref} must contain only the typ
Error message
The code loaded from %{source_ref} must contain only the type '%{name}' - it has additional definitions. What it means
Same TypeDefinitionInstantiator.create path, but raised when model.definitions.size > 1. Puppet's type autoload contract is one type per file in types/: the file must contain exactly the definition of the type it is named after. Any second definition (another type alias, a type definition, a class, a defined type) makes the file ambiguous and raises this ArgumentError.
Source
Thrown at lib/puppet/pops/loader/type_definition_instantiator.rb:21
# The TypeDefinitionInstantiator instantiates a type alias or a type definition
#
module Puppet::Pops
module Loader
class TypeDefinitionInstantiator
def self.create(loader, typed_name, source_ref, pp_code_string)
# parse and validate
parser = Parser::EvaluatingParser.new()
model = parser.parse_string(pp_code_string, source_ref)
# Only one type is allowed (and no other definitions)
name = typed_name.name
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 }View on GitHub (pinned to e227c27540)
Solutions
- Split the file so each definition lives in its own types/<name>.pp matching the type name.
- If one definition is dead/unused, delete it instead of moving it.
- Re-run the code that referenced the type to confirm the loader now resolves it.
Example fix
// before: modules/mymodule/types/mytype.pp type mymodule::mytype = Mymodule::Mytype::Inner type mymodule::mytype::inner = String[1, 50] // after: split into two files // modules/mymodule/types/mytype.pp -> type mymodule::mytype = Mymodule::Mytype::Inner // modules/mymodule/types/mytype/inner.pp -> type mymodule::mytype::inner = String[1, 50]
Defensive patterns
Strategy: validation
Validate before calling
# CI check: exactly one definition per types/*.pp file
require 'puppet'
require 'puppet/pops'
Dir['modules/*/types/**/*.pp'].each do |f|
model = Puppet::Pops::Parser::EvaluatingParser.new.parse_string(File.read(f), f)
abort "#{f}: #{model.definitions.size} definitions — only one allowed" unless model.definitions.size == 1
end Prevention
- Treat types/ files as one-definition artifacts, not scratch manifests.
- When adding a related alias, create a new file rather than appending.
- Add a CI check that parses every types/*.pp and asserts definitions.size == 1.
When it happens
Trigger: types/mytype.pp containing two aliases, e.g. `type mymodule::mytype = Mytype::Inner` followed by `type mymodule::mytype::inner = String`; or a type alias plus a `class`/`define` statement in the same file; triggered as soon as code references the type and the file is autoloaded.
Common situations: Developers grouping 'related' aliases into one file; refactoring that moved definitions together; pasting a new alias below an existing one in the same types/ file.
Related errors
- The code loaded from %{source_ref} does not define the type
- The code loaded from %{source_ref} does not define the type
- The code loaded from %{source_ref} contains additional logic
- The code loaded from %{source_ref} produced type with the wr
- Invalid entry at %{error_location}: '%{file_text}'
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/d1c52e37adc00bc3.
Report an issue: GitHub.