puppetlabs/puppet · error · ArgumentError

Template %{file} does not exist

Error message

Template %{file} does not exist

What it means

Puppet::Util::ResourceTemplate.new (resource_template.rb:49) raises ArgumentError when Puppet::FileSystem.exist?(file) is false. The path must be a concrete, readable filesystem path at construction time (a template path in a generated-resource workflow); no puppet:// URL resolution or module path lookup happens here, and evaluate() later reads the same path with UTF-8 encoding.

Source

Thrown at lib/puppet/util/resource_template.rb:49

#
#   <%= @name %>
#
# Since the ResourceTemplate class sets as instance variables all of the resource's
# parameters.
#
# Note that this example uses the generating resource as its source of
# parameters, which is generally most useful, since it allows you to configure
# the generated resource via the generating resource.
class Puppet::Util::ResourceTemplate
  include Puppet::Util::Logging

  def evaluate
    set_resource_variables
    Puppet::Util.create_erb(Puppet::FileSystem.read(@file, :encoding => 'utf-8')).result(binding)
  end

  def initialize(file, resource)
    raise ArgumentError, _("Template %{file} does not exist") % { file: file } unless Puppet::FileSystem.exist?(file)

    @file = file
    @resource = resource
  end

  private

  def set_resource_variables
    @resource.to_hash.each do |param, value|
      var = "@#{param}"
      instance_variable_set(var, value)
    end
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Verify the exact path with Puppet::FileSystem.exist?(path) before constructing and fail with your own descriptive message.
  2. Build template paths from fully-resolved module paths (Puppet::Module#template_path or File.join(module_dir, 'templates', name)) instead of string interpolation.
  3. Check the file actually shipped: inspect the module packaging; re-install the module on the node.
  4. Rescue ArgumentError at the construction site to add context (resource reference) before re-raising.

Example fix

// before
tpl = Puppet::Util::ResourceTemplate.new("#{mod}/templates/app.erb", res) # mod nil inside single-quoted source

// after
path = File.expand_path(File.join(module_dir, 'templates', 'app.erb'))
raise ArgumentError, "template #{path} missing (module not installed?)" unless Puppet::FileSystem.exist?(path)
tpl = Puppet::Util::ResourceTemplate.new(path, res)
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, "template #{path} not found" unless Puppet::FileSystem.exist?(path)
tpl = Puppet::Util::ResourceTemplate.new(path, resource)

Try / catch

begin
  Puppet::Util::ResourceTemplate.new(path, resource).evaluate
rescue ArgumentError => e
  raise if e.message !~ /does not exist/
  Puppet.err("missing template #{path} for #{resource.ref}")
  nil
end

Prevention

When it happens

Trigger: ResourceTemplate.new('/etc/puppet/templates/foo.erb', resource) where the file was never created; a path built with an unexpanded variable ('#{modulename}/templates/foo.erb' inside single quotes in Ruby DSL, so the literal '#{' is checked); a relative path resolved against the process cwd instead of the module.

Common situations: Defined types/templates shipped without installing the module on the target node; case-sensitivity mismatches on macOS/Linux (Foo.erb vs foo.erb); moving module directories without updating absolute paths; file present but path string has a typo or trailing whitespace.

Related errors


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