puppetlabs/puppet · error · ArgumentError

Given value for '%{varname}' has illegal type - got: %{type}

Error message

Given value for '%{varname}' has illegal type - got: %{type}

What it means

Each variable value must be an instance of Puppet's rich data type (TypeFactory.rich_data): scalars (String, Integer, Float, Boolean, nil/undef) plus recursively Array and Hash with String keys, and a few Puppet types. Arbitrary Ruby objects raise ArgumentError reporting the value's class.

Source

Thrown at lib/puppet/pal/pal_impl.rb:388

      node.add_server_facts({})
    end
  end
  private_class_method :prepare_node_facts

  def self.add_variables(scope, variables)
    return if variables.nil?
    unless variables.is_a?(Hash)
      raise ArgumentError, _("Given variables must be a hash, got %{type}") % { type: variables.class }
    end

    rich_data_t = Puppet::Pops::Types::TypeFactory.rich_data
    variables.each_pair do |k, v|
      unless k =~ Puppet::Pops::Patterns::VAR_NAME
        raise ArgumentError, _("Given variable '%{varname}' has illegal name") % { varname: k }
      end

      unless rich_data_t.instance?(v)
        raise ArgumentError, _("Given value for '%{varname}' has illegal type - got: %{type}") % { varname: k, type: v.class }
      end

      scope.setvar(k, v)
    end
  end
  private_class_method :add_variables

  # The main routine for script compiler
  # Picks up information from the puppet context and configures a script compiler which is given to
  # the provided block
  #
  def self.main(
    manifest:                nil,
    facts:                   {},
    variables:               {},
    target_variables:        {},
    internal_compiler_class: nil,
    set_local_facts:         true

View on GitHub (pinned to e227c27540)

Solutions

  1. Convert values to rich data before the call: Time#to_i or #to_s, Struct#to_h, Symbol#to_s
  2. Pre-check each value with Puppet::Pops::Types::TypeFactory.rich_data.instance?(v)
  3. For lazy evaluation pass Puppet::Pops::Types::PSensitiveType/PDeferred-style values rather than Ruby objects

Example fix

# before
variables: { 'started' => Time.now }

# after
variables: { 'started' => Time.now.to_i }
Defensive patterns

Strategy: validation

Validate before calling

rich = Puppet::Pops::Types::TypeFactory.rich_data
bad = variables.reject { |_, v| rich.instance?(v) }
raise ArgumentError, "non rich-data values: #{bad.keys.join(', ')}" unless bad.empty?

Type guard

def rich_data_value?(v)
  Puppet::Pops::Types::TypeFactory.rich_data.instance?(v)
end

Prevention

When it happens

Trigger: variables: { 'ts' => Time.now }, { 'obj' => Object.new }, { 'sym' => :value } or any Class/Proc/Struct instance passed as a variable value.

Common situations: Leaking Ruby runtime objects (Time, Struct, model instances) into PAL variables; assuming anything serializable-by-inspect works; passing symbols where strings are needed.

Related errors


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