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
- Verify the exact path with Puppet::FileSystem.exist?(path) before constructing and fail with your own descriptive message.
- Build template paths from fully-resolved module paths (Puppet::Module#template_path or File.join(module_dir, 'templates', name)) instead of string interpolation.
- Check the file actually shipped: inspect the module packaging; re-install the module on the node.
- 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
- Build template paths from the module's real location, never from string interpolation that can stay literal.
- Assert template existence in module smoke tests on a target-like platform (case-sensitive FS).
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
- Invalid entry at %{error_location}: '%{file_text}'
- %{mount} is already mounted at %{name} at %{error_location}
- Fileset paths must be fully qualified: %{path}
- Fileset paths must exist
- Fileset recurse parameter must not be a number anymore, plea
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/0e6a7b264efdf43c.
Report an issue: GitHub.