puppetlabs/puppet · warning

--values_file option must evaluate to a Hash or undef/nil, g

Error message

--values_file option must evaluate to a Hash or undef/nil, got: '%{template_class}'

What it means

Logged by Puppet::Face[:epp]#get_values when --values_file loads successfully but evaluates to anything other than a Hash or nil — for example a YAML list, a scalar, or a .pp file whose last expression is an Array. Template parameters must be name-to-value pairs, so the values are discarded and rendering proceeds with none.

Source

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

  def get_values(compiler, options)
    template_values = nil
    values_file = options[:values_file]
    if values_file
      begin
        case values_file
        when /\.yaml$/
          template_values = Puppet::Util::Yaml.safe_load_file(values_file, [Symbol])
        when /\.pp$/
          evaluating_parser = Puppet::Pops::Parser::EvaluatingParser.new
          template_values = evaluating_parser.evaluate_file(compiler.topscope, values_file)
        else
          Puppet.err(_("Only .yaml or .pp can be used as a --values_file"))
        end
      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

View on GitHub (pinned to e227c27540)

Solutions

  1. Make the top-level YAML structure a mapping (key: value lines, not '- key: value')
  2. In a .pp values file, end with a literal hash: { a => 1, b => 2 }
  3. Rerun and confirm the values reach the template parameters

Example fix

# before (values.yaml)
- name: app
- port: 8080

# after
name: app
port: 8080
Defensive patterns

Strategy: validation

Validate before calling

values = YAML.safe_load_file('values.yaml', [Symbol])
abort 'values file top level must be a Hash (or empty)' unless values.nil? || values.is_a?(Hash)

Type guard

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

Prevention

When it happens

Trigger: `puppet epp render tpl.epp --values_file list.yaml` where the YAML top level is '- a\n- b'; a .pp values file whose last statement returns a String or Array instead of a hash literal.

Common situations: YAML written as a list of key/value pairs instead of a mapping; .pp values files ending with an expression like $my_array instead of a hash literal.

Related errors


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