{"record":{"id":"88df2b449f485991","repo":"puppetlabs/puppet","slug":"values-option-must-evaluate-to-a-hash-or-undef","errorCode":null,"errorMessage":"--values option must evaluate to a Hash or undef, got: '%{values_class}'","messagePattern":"--values option must evaluate to a Hash or undef, got: '%(.+?)'","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/puppet/face/epp.rb","lineNumber":433,"sourceCode":"      rescue => e\n        Puppet.err(_(\"Could not load --values_file %{error}\") % { error: e.message })\n      end\n      unless template_values.nil? || template_values.is_a?(Hash)\n        Puppet.err(_(\"--values_file option must evaluate to a Hash or undef/nil, got: '%{template_class}'\") % { template_class: template_values.class })\n      end\n    end\n\n    values = options[:values]\n    if values\n      evaluating_parser = Puppet::Pops::Parser::EvaluatingParser.new\n      result = evaluating_parser.evaluate_string(compiler.topscope, values, 'values-hash')\n      case result\n      when nil\n        template_values\n      when Hash\n        template_values.nil? ? result : template_values.merge(result)\n      else\n        Puppet.err(_(\"--values option must evaluate to a Hash or undef, got: '%{values_class}'\") % { values_class: result.class })\n      end\n    else\n      template_values\n    end\n  end\n\n  def render_inline(epp_source, compiler, options)\n    template_args = get_values(compiler, options)\n    result = Puppet::Pops::Evaluator::EppEvaluator.inline_epp(compiler.topscope, epp_source, template_args)\n    if result.instance_of?(Puppet::Pops::Types::PSensitiveType::Sensitive)\n      result.unwrap\n    else\n      result\n    end\n  end\n\n  def render_file(epp_template_name, compiler, options, show_filename, file_nbr)\n    template_args = get_values(compiler, options)","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/face/epp.rb#L415-L451","documentation":"Logged by Puppet::Face[:epp]#get_values when the --values Puppet expression evaluates to something that is neither a Hash nor undef. The EvaluatingParser evaluates the string in topscope; the bad result is dropped, so the template renders with whatever --values_file supplied (or with no values at all).","triggerScenarios":"`puppet epp render -e '<%= $x %>' --values '3 + 4'` (Integer), `--values '[1,2]'` (Array), or any expression whose result class is not Hash or nil.","commonSituations":"Passing JSON-style strings or arrays instead of Puppet hash syntax; forgetting the braces around a hash literal; copy-pasting ERB locals lists into --values.","solutions":["Wrap the data in a Puppet hash literal: --values \"{msg => 'hi', port => 8080}\"","Use undef, or omit --values entirely, when no inline values are needed","For larger data, switch to --values_file with a YAML mapping so both sources merge as hashes"],"exampleFix":"# before\n$ puppet epp render tpl.epp --values 'msg'\nError: --values option must evaluate to a Hash or undef, got: 'String'\n\n# after\n$ puppet epp render tpl.epp --values \"{msg => 'hello'}\"","handlingStrategy":"validation","validationCode":"result = Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, values_str, 'values-hash')\nabort '--values must evaluate to a Puppet Hash or undef' unless result.nil? || result.is_a?(Hash)","typeGuard":"def puppet_hash?(v)\n  v.nil? || v.is_a?(Hash)\nend","tryCatchPattern":null,"preventionTips":["Always brace hash literals on the command line: --values \"{k => v}\"","Move non-trivial data into a --values_file YAML mapping"],"tags":["ruby","puppet","epp","cli","values","type-mismatch"],"backgroundTag":"template-values-type-mismatch","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}