{"record":{"id":"4ef574a67b14f6e3","repo":"puppetlabs/puppet","slug":"a-data-type-can-only-have-one-implementation","errorCode":null,"errorMessage":"a data type can only have one implementation","messagePattern":"a data type can only have one implementation","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/datatypes.rb","lineNumber":203,"sourceCode":"    end\n  end\n\n  # The TypeBuilderAPI class exposes only those methods that the builder API provides\n  # @api public\n  class TypeBuilderAPI\n    # @api private\n    def initialize(type_builder)\n      @type_builder = type_builder\n    end\n\n    def interface(type_string)\n      raise ArgumentError, _('a data type can only have one interface') unless @type_builder.interface.nil?\n\n      @type_builder.interface = type_string\n    end\n\n    def implementation(&block)\n      raise ArgumentError, _('a data type can only have one implementation') if @type_builder.has_implementation?\n\n      @type_builder.implementation = block\n    end\n\n    def implementation_class(ruby_class)\n      raise ArgumentError, _('a data type can only have one implementation') if @type_builder.has_implementation?\n\n      @type_builder.implementation_class = ruby_class\n    end\n\n    def load_file(file_name)\n      Puppet::Util::Autoload.load_file(file_name, Puppet.lookup(:current_environment))\n    end\n  end\nend\n","sourceCodeStart":185,"sourceCodeEnd":219,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/datatypes.rb#L185-L219","documentation":"TypeBuilderAPI#implementation raises ArgumentError when has_implementation? is true — i.e. the type already has an implementation from an earlier `implementation { }` block or from `implementation_class`. A Puppet data type can carry exactly one implementation.","triggerScenarios":"Two `implementation { ... }` blocks in one create_type block; `implementation_class Foo` followed by `implementation { ... }` (or the reverse order).","commonSituations":"Copying behavior from another type by pasting its implementation block alongside an existing implementation_class; merging two data types by hand.","solutions":["Keep exactly one implementation source: either one implementation block or one implementation_class, not both","To share behavior, put helpers in a Ruby module and include it inside the single implementation block","Merge the bodies of duplicate implementation blocks into one"],"exampleFix":"# before\nPuppet::DataTypes.create_type('T') do\n  interface 'attributes => {}'\n  implementation_class AcmeImpl\n  implementation { def extra; 1; end }\nend\n# after\nPuppet::DataTypes.create_type('T') do\n  interface 'attributes => {}'\n  implementation_class AcmeImpl  # sole implementation\nend","handlingStrategy":"validation","validationCode":"src = File.read(path)\nimpl_calls = src.scan(/^\\s*implementation(_class)?(\\s|\\{|\\()/).size\nraise \"#{path}: expected exactly 1 implementation, found #{impl_calls}\" unless impl_calls == 1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose one style per type: implementation block OR implementation_class, never both","Share behavior via modules included inside the single implementation block"],"tags":["puppet","data-types","pcore","duplicate-definition"],"backgroundTag":"duplicate-definition","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}