puppetlabs/puppet · error · Puppet::ParseError

%{label} equality is referencing %{attribute}. Only attribut

Error message

%{label} equality is referencing %{attribute}. Only attribute references are allowed

What it means

An equality-list entry may resolve in the type's own members, which include both attributes and functions. If the resolved member is a PFunction rather than a PAttribute, Puppet::ParseError is raised: equality is defined over attribute values only, because functions have no per-instance value to compare.

Source

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

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

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

  def [](name)
    member = @attributes[name] || @functions[name]

View on GitHub (pinned to e227c27540)

Solutions

  1. Reference an attribute instead: store the computed value in a real attribute (possibly derived at creation time) and list that attribute in equality
  2. If the function wraps an attribute, list the underlying attribute

Example fix

# before
type MyApp::G = Object[{
  attributes => { name => String },
  functions => { greeting => Callable[[], String] },
  equality => ['greeting']    # functions cannot participate in equality
}]

# after
type MyApp::G = Object[{
  attributes => { name => String },
  functions => { greeting => Callable[[], String] },
  equality => ['name']
}]
Defensive patterns

Strategy: validation

Validate before calling

# equality entries must resolve to PAttribute instances, never PFunction
bad = equality_list.reject { |n| (attrs[n] || parent_members[n]).is_a?(Puppet::Pops::Types::PAttribute) }
raise "equality references functions or non-attributes: #{bad.inspect}" unless bad.empty?

Type guard

def attribute?(type, name)
  member = type.attributes(true)[name] || (type.parent.respond_to?(:members) && type.parent.members(true)[name])
  member.is_a?(Puppet::Pops::Types::PAttribute)
end

Try / catch

begin
  Puppet::Pops::Types::PObjectType.new(name, init_hash)
rescue Puppet::ParseError => e
  raise unless e.message =~ /Only attribute references are allowed/
  raise  # e.message names the function; reference an attribute instead
end

Prevention

When it happens

Trigger: equality => ['greeting'] where greeting is declared under functions => { greeting => Callable[[], String] }. The lookup @attributes[attr_name] || @functions[attr_name] succeeds, but the member is not a PAttribute, so the raise fires.

Common situations: Trying to include a computed/derived value in equality by naming the function that computes it; type definitions where a function and the intended equality participant were confused.

Related errors


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