{"record":{"id":"df084c9c3706b0ef","repo":"puppetlabs/puppet","slug":"given-value-for-varname-has-illegal-type-go","errorCode":null,"errorMessage":"Given value for '%{varname}' has illegal type - got: %{type}","messagePattern":"Given value for '%(.+?)' has illegal type - got: %(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pal/pal_impl.rb","lineNumber":388,"sourceCode":"      node.add_server_facts({})\n    end\n  end\n  private_class_method :prepare_node_facts\n\n  def self.add_variables(scope, variables)\n    return if variables.nil?\n    unless variables.is_a?(Hash)\n      raise ArgumentError, _(\"Given variables must be a hash, got %{type}\") % { type: variables.class }\n    end\n\n    rich_data_t = Puppet::Pops::Types::TypeFactory.rich_data\n    variables.each_pair do |k, v|\n      unless k =~ Puppet::Pops::Patterns::VAR_NAME\n        raise ArgumentError, _(\"Given variable '%{varname}' has illegal name\") % { varname: k }\n      end\n\n      unless rich_data_t.instance?(v)\n        raise ArgumentError, _(\"Given value for '%{varname}' has illegal type - got: %{type}\") % { varname: k, type: v.class }\n      end\n\n      scope.setvar(k, v)\n    end\n  end\n  private_class_method :add_variables\n\n  # The main routine for script compiler\n  # Picks up information from the puppet context and configures a script compiler which is given to\n  # the provided block\n  #\n  def self.main(\n    manifest:                nil,\n    facts:                   {},\n    variables:               {},\n    target_variables:        {},\n    internal_compiler_class: nil,\n    set_local_facts:         true","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pal/pal_impl.rb#L370-L406","documentation":"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.","triggerScenarios":"variables: { 'ts' => Time.now }, { 'obj' => Object.new }, { 'sym' => :value } or any Class/Proc/Struct instance passed as a variable value.","commonSituations":"Leaking Ruby runtime objects (Time, Struct, model instances) into PAL variables; assuming anything serializable-by-inspect works; passing symbols where strings are needed.","solutions":["Convert values to rich data before the call: Time#to_i or #to_s, Struct#to_h, Symbol#to_s","Pre-check each value with Puppet::Pops::Types::TypeFactory.rich_data.instance?(v)","For lazy evaluation pass Puppet::Pops::Types::PSensitiveType/PDeferred-style values rather than Ruby objects"],"exampleFix":"# before\nvariables: { 'started' => Time.now }\n\n# after\nvariables: { 'started' => Time.now.to_i }","handlingStrategy":"validation","validationCode":"rich = Puppet::Pops::Types::TypeFactory.rich_data\nbad = variables.reject { |_, v| rich.instance?(v) }\nraise ArgumentError, \"non rich-data values: #{bad.keys.join(', ')}\" unless bad.empty?","typeGuard":"def rich_data_value?(v)\n  Puppet::Pops::Types::TypeFactory.rich_data.instance?(v)\nend","tryCatchPattern":null,"preventionTips":["Restrict variable payloads to JSON-serializable data (String/Integer/Float/Boolean/nil/Array/Hash)","Convert Time and Struct objects with to_i/to_s/to_h before injection"],"tags":["puppet","pal","variables","type-validation","serialization"],"backgroundTag":"unsupported-value-type","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}