puppetlabs/puppet · error · Puppet::ParseError

%{label} equality is referencing constant %{attribute}. Refe

Error message

%{label} equality is referencing constant %{attribute}. Reference to constant is not allowed in equality

What it means

Constants declared in an Object type are folded into the attribute map with kind ATTRIBUTE_KIND_CONSTANT, and by design they are excluded from equality - every instance of the type carries the same constant value, so comparing it is meaningless and it cannot be overridden. Referencing a constant-kind attribute in an explicit equality list therefore raises Puppet::ParseError.

Source

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

            # 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
      equality.freeze
    end
    @equality = equality

    @checks = init_hash[KEY_CHECKS]
    init_annotatable(init_hash)
  end

  def [](name)
    member = @attributes[name] || @functions[name]
    if member.nil?
      rp = resolved_parent
      member = rp[name] if rp.is_a?(PObjectType)
    end

View on GitHub (pinned to e227c27540)

Solutions

  1. Remove the constant from the equality list - constants never distinguish instances
  2. If the value truly varies per instance and must affect equality, declare it as a regular attribute instead of a constant

Example fix

# before
type MyApp::T = Object[{
  constants => { version => '1.0' },
  equality => ['version']
}]

# after
type MyApp::T = Object[{
  constants => { version => '1.0' }
  # default equality covers all non-constant attributes
}]
Defensive patterns

Strategy: validation

Validate before calling

# constants must not appear in the equality list
const_names = type.attributes(true).select { |_, a| a.kind == Puppet::Pops::Types::PAttribute::ATTRIBUTE_KIND_CONSTANT }.keys
bad = equality_list & const_names
raise "equality references constants: #{bad.inspect}" unless bad.empty?

Try / catch

begin
  Puppet::Pops::Types::PObjectType.new(name, init_hash)
rescue Puppet::ParseError => e
  raise unless e.message =~ /Reference to constant is not allowed in equality/
  raise  # drop the constant from the equality list
end

Prevention

When it happens

Trigger: A type with constants => { version => '1.0' } that also lists equality => ['version']. The entry resolves to a PAttribute, passes the existence and type checks, but its kind is constant, triggering the final check in the equality loop.

Common situations: Adding a constant to a type whose equality list previously referenced a regular attribute of the same name; attempting to make version/build metadata part of instance identity.

Related errors


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