puppetlabs/puppet · warning

--values option must evaluate to a Hash or undef, got: '%{va

Error message

--values option must evaluate to a Hash or undef, got: '%{values_class}'

What it means

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).

Source

Thrown at lib/puppet/face/epp.rb:433

      rescue => e
        Puppet.err(_("Could not load --values_file %{error}") % { error: e.message })
      end
      unless template_values.nil? || template_values.is_a?(Hash)
        Puppet.err(_("--values_file option must evaluate to a Hash or undef/nil, got: '%{template_class}'") % { template_class: template_values.class })
      end
    end

    values = options[:values]
    if values
      evaluating_parser = Puppet::Pops::Parser::EvaluatingParser.new
      result = evaluating_parser.evaluate_string(compiler.topscope, values, 'values-hash')
      case result
      when nil
        template_values
      when Hash
        template_values.nil? ? result : template_values.merge(result)
      else
        Puppet.err(_("--values option must evaluate to a Hash or undef, got: '%{values_class}'") % { values_class: result.class })
      end
    else
      template_values
    end
  end

  def render_inline(epp_source, compiler, options)
    template_args = get_values(compiler, options)
    result = Puppet::Pops::Evaluator::EppEvaluator.inline_epp(compiler.topscope, epp_source, template_args)
    if result.instance_of?(Puppet::Pops::Types::PSensitiveType::Sensitive)
      result.unwrap
    else
      result
    end
  end

  def render_file(epp_template_name, compiler, options, show_filename, file_nbr)
    template_args = get_values(compiler, options)

View on GitHub (pinned to e227c27540)

Solutions

  1. Wrap the data in a Puppet hash literal: --values "{msg => 'hi', port => 8080}"
  2. Use undef, or omit --values entirely, when no inline values are needed
  3. For larger data, switch to --values_file with a YAML mapping so both sources merge as hashes

Example fix

# before
$ puppet epp render tpl.epp --values 'msg'
Error: --values option must evaluate to a Hash or undef, got: 'String'

# after
$ puppet epp render tpl.epp --values "{msg => 'hello'}"
Defensive patterns

Strategy: validation

Validate before calling

result = Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, values_str, 'values-hash')
abort '--values must evaluate to a Puppet Hash or undef' unless result.nil? || result.is_a?(Hash)

Type guard

def puppet_hash?(v)
  v.nil? || v.is_a?(Hash)
end

Prevention

When it happens

Trigger: `puppet epp render -e '<%= $x %>' --values '3 + 4'` (Integer), `--values '[1,2]'` (Array), or any expression whose result class is not Hash or nil.

Common situations: 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.

Related errors


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