puppetlabs/puppet · error · ArgumentError

a data type can only have one interface

Error message

a data type can only have one interface

What it means

TypeBuilderAPI#interface raises ArgumentError when an interface was already assigned — a data type's interface may be declared exactly once per create_type block. The guard is `unless @type_builder.interface.nil?`.

Source

Thrown at lib/puppet/datatypes.rb:197

      end
      created_type
    end

    def has_implementation?
      !(@implementation_class.nil? && @implementation.nil?)
    end
  end

  # The TypeBuilderAPI class exposes only those methods that the builder API provides
  # @api public
  class TypeBuilderAPI
    # @api private
    def initialize(type_builder)
      @type_builder = type_builder
    end

    def interface(type_string)
      raise ArgumentError, _('a data type can only have one interface') unless @type_builder.interface.nil?

      @type_builder.interface = type_string
    end

    def implementation(&block)
      raise ArgumentError, _('a data type can only have one implementation') if @type_builder.has_implementation?

      @type_builder.implementation = block
    end

    def implementation_class(ruby_class)
      raise ArgumentError, _('a data type can only have one implementation') if @type_builder.has_implementation?

      @type_builder.implementation_class = ruby_class
    end

    def load_file(file_name)
      Puppet::Util::Autoload.load_file(file_name, Puppet.lookup(:current_environment))

View on GitHub (pinned to e227c27540)

Solutions

  1. Delete all but one interface declaration in the block
  2. If you meant to merge two definitions, combine their attribute hashes into a single interface string
  3. For generated code, emit the interface call once and assert on it (see validation)

Example fix

# before
Puppet::DataTypes.create_type('T') do
  interface 'attributes => { a => String }'
  interface 'attributes => { b => Integer }'
end
# after
Puppet::DataTypes.create_type('T') do
  interface 'attributes => { a => String, b => Integer }'
end
Defensive patterns

Strategy: validation

Validate before calling

# authoring-time lint: one interface call per type file
src = File.read(path)
count = src.scan(/^\s*interface(\s|<<-)/).size
raise "#{path}: expected exactly 1 interface call, found #{count}" unless count == 1

Prevention

When it happens

Trigger: Two `interface '...'` calls inside one Puppet::DataTypes.create_type block — typically a copied example followed by the author's own declaration, or code generators concatenating fragments.

Common situations: Copy-paste editing of data type definitions; template systems that append a default interface after a user-supplied one.

Related errors


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