puppetlabs/puppet · error · Puppet::ParseError

%{label} of kind '%{kind}' cannot be combined with an attrib

Error message

%{label} of kind '%{kind}' cannot be combined with an attribute value

What it means

Attributes of kind 'derived' or 'given_or_derived' compute their value when an instance is created, so they cannot declare a static 'value'. PAttribute#initialize raises this Puppet::ParseError when the init hash contains both a computed kind and a 'value' key.

Source

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

    def initialize(name, container, init_hash)
      super(name, container, TypeAsserter.assert_instance_of(nil, TYPE_ATTRIBUTE, init_hash) { "initializer for #{self.class.label(container, name)}" })
      if name == Serialization::PCORE_TYPE_KEY || name == Serialization::PCORE_VALUE_KEY
        raise Puppet::ParseError, _("The attribute '%{name}' is reserved and cannot be used") % { name: name }
      end

      @kind = init_hash[KEY_KIND]
      if @kind == ATTRIBUTE_KIND_CONSTANT # final is implied
        if init_hash.include?(KEY_FINAL) && !@final
          # TRANSLATOR 'final => false' is puppet syntax and should not be translated
          raise Puppet::ParseError, _("%{label} of kind 'constant' cannot be combined with final => false") % { label: label }
        end

        @final = true
      end

      if init_hash.include?(KEY_VALUE)
        if @kind == ATTRIBUTE_KIND_DERIVED || @kind == ATTRIBUTE_KIND_GIVEN_OR_DERIVED
          raise Puppet::ParseError, _("%{label} of kind '%{kind}' cannot be combined with an attribute value") % { label: label, kind: @kind }
        end

        v = init_hash[KEY_VALUE]
        @value = v == :default ? v : TypeAsserter.assert_instance_of(nil, type, v) { "#{label} #{KEY_VALUE}" }
      else
        raise Puppet::ParseError, _("%{label} of kind 'constant' requires a value") % { label: label } if @kind == ATTRIBUTE_KIND_CONSTANT

        @value = :undef # Not to be confused with nil or :default
      end
    end

    def callable_type
      TYPE_ATTRIBUTE_CALLABLE
    end

    # @api public
    def eql?(o)
      super && @kind == o.kind && @value == (o.value? ? o.value : :undef)

View on GitHub (pinned to e227c27540)

Solutions

  1. Remove the 'value' key from derived/given_or_derived attributes.
  2. If a fixed value is actually wanted, use kind 'constant' (with a value) or a plain attribute with a default.
  3. Re-read the kind semantics: 'given' accepts constructor input, 'derived' computes, only plain/constant attributes may carry defaults.

Example fix

# before
{'type' => Integer, 'kind' => 'derived', 'value' => 3}

# after
{'type' => Integer, 'kind' => 'derived'}
Defensive patterns

Strategy: validation

Validate before calling

# Ruby — reject value on computed kinds before declaration
if %w[derived given_or_derived].include?(h['kind']) && h.key?('value')
  fail("kind #{h['kind']} cannot declare a value")
end

Type guard

def value_allowed_for_kind?(kind)
  kind != 'derived' && kind != 'given_or_derived'
end

Prevention

When it happens

Trigger: An attribute hash like {'type' => Integer, 'kind' => 'derived', 'value' => 3}; equally for kind 'given_or_derived' with any 'value' entry.

Common situations: Converting a regular attribute (with a default value) to a derived one and leaving the default in place; template code that attaches default values to every attribute regardless of kind.

Related errors


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