{"record":{"id":"d1c52e37adc00bc3","repo":"puppetlabs/puppet","slug":"the-code-loaded-from-source-ref-must-contain-on-d1c52e","errorCode":null,"errorMessage":"The code loaded from %{source_ref} must contain only the type '%{name}' - it has additional definitions.","messagePattern":"The code loaded from %(.+?) must contain only the type '%(.+?)' - it has additional definitions\\.","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/loader/type_definition_instantiator.rb","lineNumber":21,"sourceCode":"# The TypeDefinitionInstantiator instantiates a type alias or a type definition\n#\nmodule Puppet::Pops\nmodule Loader\nclass TypeDefinitionInstantiator\n  def self.create(loader, typed_name, source_ref, pp_code_string)\n    # parse and validate\n    parser = Parser::EvaluatingParser.new()\n    model = parser.parse_string(pp_code_string, source_ref)\n    # Only one type is allowed (and no other definitions)\n\n    name = typed_name.name\n    case model.definitions.size\n    when 0\n      raise ArgumentError, _(\"The code loaded from %{source_ref} does not define the type '%{name}' - it is empty.\") % { source_ref: source_ref, name: name }\n    when 1\n      # ok\n    else\n      raise ArgumentError,\n            _(\"The code loaded from %{source_ref} must contain only the type '%{name}' - it has additional definitions.\") % { source_ref: source_ref, name: name }\n    end\n    type_definition = model.definitions[0]\n\n    unless type_definition.is_a?(Model::TypeAlias) || type_definition.is_a?(Model::TypeDefinition)\n      raise ArgumentError,\n            _(\"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 }\n    end\n\n    actual_name = type_definition.name\n    unless name == actual_name.downcase\n      raise ArgumentError,\n            _(\"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 }\n    end\n\n    unless model.body == type_definition\n      raise ArgumentError,\n            _(\"The code loaded from %{source_ref} contains additional logic - can only contain the type '%{name}'\") % { source_ref: source_ref, name: name }","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/loader/type_definition_instantiator.rb#L3-L39","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: modules/mymodule/types/mytype.pp\ntype mymodule::mytype = Mymodule::Mytype::Inner\ntype mymodule::mytype::inner = String[1, 50]\n\n// after: split into two files\n// modules/mymodule/types/mytype.pp -> type mymodule::mytype = Mymodule::Mytype::Inner\n// modules/mymodule/types/mytype/inner.pp -> type mymodule::mytype::inner = String[1, 50]","handlingStrategy":"validation","validationCode":"# CI check: exactly one definition per types/*.pp file\nrequire 'puppet'\nrequire 'puppet/pops'\n\nDir['modules/*/types/**/*.pp'].each do |f|\n  model = Puppet::Pops::Parser::EvaluatingParser.new.parse_string(File.read(f), f)\n  abort \"#{f}: #{model.definitions.size} definitions — only one allowed\" unless model.definitions.size == 1\nend","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["puppet","type-alias","types-directory","one-definition-per-file","argumenterror"],"backgroundTag":"puppet-type-definition-multiple-definitions","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}