{"record":{"id":"69e30d1e08268d06","repo":"puppetlabs/puppet","slug":"the-code-loaded-from-source-ref-does-not-seem-t","errorCode":null,"errorMessage":"The code loaded from %{source_ref} does not seem to be a Puppet 5x API data type - no create_type call.","messagePattern":"The code loaded from %(.+?) does not seem to be a Puppet 5x API data type - no create_type call\\.","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/loader/ruby_data_type_instantiator.rb","lineNumber":19,"sourceCode":"# frozen_string_literal: true\n\n# The RubyTypeInstantiator instantiates a data type from the ruby source\n# that calls Puppet::DataTypes.create_type.\n#\nclass Puppet::Pops::Loader::RubyDataTypeInstantiator\n  # Produces an instance of class derived from PAnyType class with the given typed_name, or fails with an error if the\n  # given ruby source does not produce this instance when evaluated.\n  #\n  # @param loader [Puppet::Pops::Loader::Loader] The loader the type is associated with\n  # @param typed_name [Puppet::Pops::Loader::TypedName] the type / name of the type to load\n  # @param source_ref [URI, String] a reference to the source / origin of the ruby code to evaluate\n  # @param ruby_code_string [String] ruby code in a string\n  #\n  # @return [Puppet::Pops::Types::PAnyType] - an instantiated data type associated with the given loader\n  #\n  def self.create(loader, typed_name, source_ref, ruby_code_string)\n    unless ruby_code_string.is_a?(String) && ruby_code_string =~ /Puppet::DataTypes\\.create_type/\n      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 }\n    end\n\n    # make the private loader available in a binding to allow it to be passed on\n    loader_for_type = loader.private_loader\n    here = get_binding(loader_for_type)\n    created = eval(ruby_code_string, here, source_ref, 1) # rubocop:disable Security/Eval\n    unless created.is_a?(Puppet::Pops::Types::PAnyType)\n      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 }\n    end\n    unless created.name.casecmp(typed_name.name) == 0\n      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 }\n    end\n\n    created\n  end\n\n  # Produces a binding where the given loader is bound as a local variable (loader_injected_arg). This variable can be used in loaded\n  # ruby code - e.g. to call Puppet::Function.create_loaded_function(:name, loader,...)","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/loader/ruby_data_type_instantiator.rb#L1-L37","documentation":"Raised by RubyDataTypeInstantiator when Ruby source being loaded as a data type does not contain a Puppet::DataTypes.create_type call (a simple regex gate on the source string before eval). Ruby data types must be defined through that API; anything else fails fast instead of being evaluated.","triggerScenarios":"`ruby_code_string !~ /Puppet::DataTypes\\.create_type/`: the .rb file resolved for a data type name lacks the literal call -- e.g. it defines a 4x function via Puppet::Functions.create_function, or is plain Ruby with no type creation.","commonSituations":"Placing a non-data-type .rb file where the data type loader resolves it; refactoring away from the DataTypes API; wrong name-to-file mapping causing the loader to open the wrong source.","solutions":["Define the type with Puppet::DataTypes.create_type('<name>') do ... end in the Ruby file","If the file is Puppet language (type alias), move it to the Puppet-language type location instead of the Ruby path","Verify the file named by source_ref is the one you intended to load"],"exampleFix":"# before - lib/puppet/datatypes/mymod/port.rb\nPuppet::Functions.create_function(:'mymod::port') do\n  def port(x); x; end\nend\n\n# after\nPuppet::DataTypes.create_type('mymod::port') do\n  interface <<-PUPPET\n    attributes => {\n      value => { type => Integer, value => 8080 }\n    }\n  PUPPET\nend","handlingStrategy":"validation","validationCode":"raise ArgumentError, \"#{path} is not a Puppet 5x data type\" unless ruby_source.is_a?(String) && ruby_source =~ /Puppet::DataTypes\\.create_type/","typeGuard":null,"tryCatchPattern":"begin\n  type = loader.load_typed(typed_name)\nrescue ArgumentError => e\n  raise unless e.message.include?('no create_type call')\n  warn \"not a Ruby data type: #{e.message}\"\nend","preventionTips":["Keep only Puppet::DataTypes.create_type files in the Ruby data type path","During 3x/4x migration, verify each file uses the API matching its directory","Grep shipped .rb data type files for create_type in CI"],"tags":["puppet","data-type","ruby","loader","eval"],"backgroundTag":"puppet-data-type-load-validation","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}