puppetlabs/puppet · error

--- #

Error message

--- #{epp_template_name}

What it means

Printed by the `puppet epp render` face while rendering several templates: on Puppet::ParseError for one template, with show_filename on, '--- <template>' is printed as a header and the original ParseError is re-raised, aborting the whole render run at the first broken template.

Solutions

  1. Fix the parse error reported in the raised detail right after the header (it names file and line)
  2. Pre-validate the batch first: `puppet epp validate a.epp b.epp`
  3. Keep `puppet epp validate` as a CI gate so render batches never include broken templates

Example fix

# before (tpl.epp)
<%= $data.map |$x| { $x  %>

# after
<%= $data.map |$x| { $x } %>
Defensive patterns

Strategy: try-catch

Validate before calling

require 'puppet/pops/parser/evaluating_parser'

templates.each do |t|
  Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new.parse_file(t)
rescue Puppet::ParseError => e
  abort "#{t}: #{e.message}"
end

Try / catch

templates.each do |t|
  begin
    out << render_template(t)
  rescue Puppet::ParseError => e
    Puppet.err "--- #{t}"
    raise e                 # face aborts at first bad template; or collect and continue
  end
end

Prevention

When it happens

Trigger: `puppet epp render a.epp b.epp` where any listed template (or one resolved from the module path) contains invalid EPP that EppEvaluator.epp cannot parse.

Common situations: Batch-rendering module templates in CI after a refactor; templates referencing removed Puppet functions; templates valid only under a different Puppet version.

Related errors


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

Appendix: source

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

    begin
      if show_filename && options[:header]
        output << "\n" unless file_nbr == 1
        output << "--- #{epp_template_name}\n"
      end
      # Change to an absolute file only if reference is to a an existing file. Note that an absolute file must be used
      # or the template must be found on the module path when calling the epp evaluator.
      template_file = Puppet::Parser::Files.find_template(epp_template_name, compiler.environment)
      if template_file.nil? && Puppet::FileSystem.exist?(epp_template_name)
        epp_template_name = File.expand_path(epp_template_name)
      end
      result = Puppet::Pops::Evaluator::EppEvaluator.epp(compiler.topscope, epp_template_name, compiler.environment, template_args)
      if result.instance_of?(Puppet::Pops::Types::PSensitiveType::Sensitive)
        output << result.unwrap
      else
        output << result
      end
    rescue Puppet::ParseError => detail
      Puppet.err("--- #{epp_template_name}") if show_filename
      raise detail
    end
    output
  end

  # @api private
  def validate_template(template)
    parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new()
    parser.parse_file(template)
    true
  rescue => detail
    Puppet.log_exception(detail)
    false
  end

  # @api private
  def validate_template_string(source)
    parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new()

View on GitHub (pinned to e227c27540)