puppetlabs/puppet · error · ArgumentError

Creation of new instance of type '%{type_name}' is not suppo

Error message

Creation of new instance of type '%{type_name}' is not supported

What it means

Computing the constructor of Init[T] (used by Init[T].new(...)) filters out types that cannot be meaningfully instantiated: Optional and NotUndef are wrapper types, and a nested Init would recurse endlessly when creating instances. Types whose new_function also raises ArgumentError fall into the same rescue, which re-raises with this clearer message naming the offending type.

Source

Thrown at lib/puppet/pops/types/p_init_type.rb:160

  def assert_initialized
    return self if @initialized

    @initialized = true
    @self_recursion = true

    begin
      # Filter out types that will provide a new_function but are unsuitable to be contained in Init
      #
      # Calling Init#new would cause endless recursion
      # The Optional is the same as Variant[T,Undef].
      # The NotUndef is not meaningful to create instances of
      if @type.instance_of?(PInitType) || @type.instance_of?(POptionalType) || @type.instance_of?(PNotUndefType)
        raise ArgumentError
      end

      new_func = @type.new_function
    rescue ArgumentError
      raise ArgumentError, _("Creation of new instance of type '%{type_name}' is not supported") % { type_name: @type.to_s }
    end
    param_tuples = new_func.dispatcher.signatures.map { |closure| closure.type.param_types }

    # An instance of the contained type is always a match to this type.
    single_types = [@type]

    if @init_args.empty?
      # A value that is assignable to the type of a single parameter is also a match
      single_tuples, other_tuples = param_tuples.partition { |tuple| EXACTLY_ONE == tuple.size_range }
      single_types.concat(single_tuples.map { |tuple| tuple.types[0] })
    else
      tc = TypeCalculator.singleton
      init_arg_types = @init_args.map { |arg| tc.infer_set(arg) }
      arg_count = 1 + init_arg_types.size

      # disqualify all parameter tuples that doesn't allow one value (type unknown at ths stage) + init args.
      param_tuples = param_tuples.select do |tuple|
        min, max = tuple.size_range

View on GitHub (pinned to e227c27540)

Solutions

  1. Parameterize the inner type directly: use Init[String] instead of Init[Optional[String]].
  2. Strip Optional/NotUndef/Init wrappers before building the Init type: unwrap to the contained type first.
  3. If you wrap types generically, skip wrapping when the type is Optional/NotUndef/Init (or any type without a new_function).

Example fix

# before
$v = Init[Optional[String]].new('hello')

# after
$v = Init[String].new('hello')
Defensive patterns

Strategy: type-guard

Validate before calling

# Ruby — skip wrapper types when generating Init types
WRAPPERS = [Puppet::Pops::Types::PInitType, Puppet::Pops::Types::POptionalType, Puppet::Pops::Types::PNotUndefType]
inner = WRAPPERS.any? { |w| t.instance_of?(w) } ? nil : t

Type guard

def init_constructible?(t)
  !t.instance_of?(Puppet::Pops::Types::PInitType) &&
    !t.instance_of?(Puppet::Pops::Types::POptionalType) &&
    !t.instance_of?(Puppet::Pops::Types::PNotUndefType)
end

Try / catch

begin
  init_t.new_function
rescue ArgumentError => e
  raise TypeError, "cannot instantiate #{init_t}: #{e.message}" # or fall back to the inner type
end

Prevention

When it happens

Trigger: Instantiating Init[Optional[String]].new('x'), Init[NotUndef[Integer]].new(3), or Init[Init[String]].new('x') in Puppet DSL; or calling new_function on such a PInitType from Ruby (e.g. generic code that wraps inferred types in Init).

Common situations: Code that programmatically wraps arbitrary inferred types in Init and later instantiates them (TypeCalculator results often contain Optional); template libraries that 'add defaults' by wrapping every type in Init; copying Init examples from type-algebra docs into constructors.

Related errors


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