puppetlabs/puppet · error · Puppet::ParseError

The %{label}-Type cannot be parameterized using []

Error message

The %{label}-Type cannot be parameterized using []

What it means

PObjectTypeExtension wraps an Object type parameterized with [], e.g. MyApp::Color[3]. Parameterization only works when the type declares type_parameters (own or inherited); the constructor raises Puppet::ParseError when the base type's type_parameters map is empty, because there is nothing for the bracket arguments to bind to.

Source

Thrown at lib/puppet/pops/types/p_object_type_extension.rb:55

  # @api private
  def self.create_from_instance(base_type, instance)
    type_parameters = base_type.type_parameters(true)
    attrs = base_type.attributes(true)
    params = type_parameters.keys.map do |pn|
      attr = attrs[pn]
      attr.nil? ? nil : instance.send(pn)
    end
    create(base_type, params)
  end

  def [](name)
    @base_type[name]
  end

  # @api private
  def initialize(base_type, init_parameters)
    pts = base_type.type_parameters(true)
    raise Puppet::ParseError, _('The %{label}-Type cannot be parameterized using []') % { label: base_type.label } if pts.empty?

    @base_type = base_type

    named_args = init_parameters.size == 1 && init_parameters[0].is_a?(Hash)
    if named_args
      # Catch case when first parameter is an assignable Hash
      named_args = pts.size >= 1 && !pts.values[0].type.instance?(init_parameters[0])
    end

    by_name = {}
    if named_args
      hash = init_parameters[0]
      hash.each_pair do |pn, pv|
        tp = pts[pn]
        if tp.nil?
          raise Puppet::ParseError, _("'%{pn}' is not a known type parameter for %{label}-Type") % { pn: pn, label: base_type.label }
        end

View on GitHub (pinned to e227c27540)

Solutions

  1. If you want a parameterizable type, declare type_parameters => { channel => Type[Integer] } (each with a type) in the Object definition, then use MyApp::Color[3]
  2. If you meant to match instances by attribute values, do not parameterize: rely on type inference or write a function that checks the attribute values

Example fix

# before
type MyApp::Color = Object[{ attributes => { value => Integer } }]
$three = MyApp::Color[3]        # ParseError: no type_parameters

# after
type MyApp::Color = Object[{
  type_parameters => { channel => Integer },
  attributes => { value => Integer }
}]
$three = MyApp::Color[3]
Defensive patterns

Strategy: type-guard

Validate before calling

# Ruby: only parameterize types that declare type parameters
pts = base_type.type_parameters(true)
raise "#{base_type.label} declares no type_parameters; cannot use []" if pts.empty?

Type guard

def parameterizable?(type)
  type.respond_to?(:type_parameters) && !type.type_parameters(true).empty?
end

Try / catch

begin
  Puppet::Pops::Types::PObjectTypeExtension.create(base_type, args)
rescue Puppet::ParseError => e
  raise unless e.message =~ /cannot be parameterized using \[\]/
  base_type  # fall back semantics live with the caller: use the unparameterized type deliberately
end

Prevention

When it happens

Trigger: Writing MyApp::Color[3] or MyApp::Color[{channel => 3}] in Puppet code when the MyApp::Color Object type declares only attributes (or nothing) under type_parameters. Attributes do not make a type parameterizable - only type_parameters do.

Common situations: Confusing attributes with type_parameters: expecting MyType[{attr => val}] to act as a struct-style instance check; using a type alias parameterization style on a plain Object type; migrating from Variant/Struct patterns.

Related errors


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