puppetlabs/puppet · error · Puppet::ParseError

equality is referencing which is included in equality of

Error message

%{label} equality is referencing %{attribute} which is included in equality of %{including_parent}

What it means

When a child type declares an explicit equality list, each referenced attribute that exists in the parent is checked against the parent's equality_attributes. Re-listing an attribute that the parent's equality already includes would make the child's equality ambiguous, so Puppet::ParseError is raised naming both the child and the type ('including_parent') whose equality already contains the attribute.

Solutions

  1. In the child's equality list, reference only attributes new to the child; inherited attributes already in the parent's equality are automatically covered
  2. If the parent should no longer own that attribute's equality, move the equality declaration down: remove it from the parent and declare it in the child

Example fix

# before
type MyApp::Base = Object[{ equality => ['a'] }]
type MyApp::Child = Object[{
  parent => 'MyApp::Base',
  equality => ['a', 'b']      # 'a' already in MyApp::Base equality
}]

# after
type MyApp::Child = Object[{
  parent => 'MyApp::Base',
  equality => ['b']
}]
Defensive patterns

Strategy: validation

Validate before calling

# before declaring child equality, check the parent's equality attributes
parent_eq = parent_object_type.equality_attributes
repeated = declared_equality & parent_eq.map { |a| a.name }
raise "attributes already in parent equality: #{repeated.inspect}" unless repeated.empty?

Try / catch

begin
  Puppet::Pops::Types::PObjectType.new(name, init_hash)
rescue Puppet::ParseError => e
  raise unless e.message =~ /which is included in equality of/
  raise  # e.message names both types; drop the inherited attribute from the child list
end

Prevention

When it happens

Trigger: Parent declares equality => ['a']; child declares parent => Parent together with equality => ['a', 'b']. The 'a' entry resolves to a parent PAttribute already present in parent_object_type.equality_attributes, triggering the raise. Trigger also fires for deeper ancestry since find_equality_definer_of walks up.

Common situations: Extending a base type and copy-pasting its equality list into the child; refactoring a type hierarchy where equality was previously duplicated across levels.

Related errors


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

Appendix: source

Thrown at lib/puppet/pops/types/p_object_type.rb:801

    equality = init_hash[KEY_EQUALITY]
    equality = [equality] if equality.is_a?(String)
    if equality.is_a?(Array)
      unless equality.empty?
        # TRANSLATORS equality_include_type = false should not be translated
        raise Puppet::ParseError, _('equality_include_type = false cannot be combined with non empty equality specification') unless @equality_include_type

        parent_eq_attrs = nil
        equality.each do |attr_name|
          attr = parent_members[attr_name]
          if attr.nil?
            attr = @attributes[attr_name] || @functions[attr_name]
          elsif attr.is_a?(PAttribute)
            # Assert that attribute is not already include by parent equality
            parent_eq_attrs ||= parent_object_type.equality_attributes
            if parent_eq_attrs.include?(attr_name)
              including_parent = find_equality_definer_of(attr)
              raise Puppet::ParseError, _("%{label} equality is referencing %{attribute} which is included in equality of %{including_parent}") %
                                        { label: label, attribute: attr.label, including_parent: including_parent.label }
            end
          end

          unless attr.is_a?(PAttribute)
            if attr.nil?
              raise Puppet::ParseError, _("%{label} equality is referencing non existent attribute '%{attribute}'") % { label: label, attribute: attr_name }
            end

            raise Puppet::ParseError, _("%{label} equality is referencing %{attribute}. Only attribute references are allowed") %
                                      { label: label, attribute: attr.label }
          end
          if attr.kind == ATTRIBUTE_KIND_CONSTANT
            raise Puppet::ParseError, _("%{label} equality is referencing constant %{attribute}.") % { label: label, attribute: attr.label } + ' ' +
                                      _("Reference to constant is not allowed in equality")
          end
        end
      end

View on GitHub (pinned to e227c27540)