puppetlabs/puppet · error · Puppet::Error

One or more file(s) specified did not exist

Error message

One or more file(s) specified did not exist:
%{missing_files_list}

What it means

Raised by the `validate` action of the `puppet epp` face when one or more of the requested templates resolved to no file: `effective_template` returns nil for paths that neither exist on disk nor resolve to a `<module>/template.epp` form in the given environment. Remaining templates are still validated first; afterwards the missing paths are listed (indented, one per line) and the action fails. The two-branch structure means this error is raised only when missing_files is non-empty; validation failures alone raise a different error.

Solutions

  1. Check every path in the list with ls, or switch to the module form `puppet epp validate module/template.epp`
  2. Run from the module directory or pass absolute paths
  3. Verify the module exists in the environment being used (`puppet module list`)
  4. Quote globs in scripts so shell expansion doesn't silently drop entries

Example fix

# before
puppet epp validate app/temple.epp        # typo
# after
puppet epp validate app/template.epp
# or module form
puppet epp validate mymod/template.epp
Defensive patterns

Strategy: validation

Validate before calling

missing = templates.reject { |t| File.exist?(t) || t.include?('/') && Puppet.lookup(:current_environment).module(t.split('/').first) }
abort "templates not found: #{missing.join(', ')}" unless missing.empty?

Prevention

When it happens

Trigger: `puppet epp validate missing.epp`, or a file list where one path is wrong; `puppet epp validate mymod/nope.epp` where the module form does not resolve; relative paths evaluated from the wrong cwd.

Common situations: Typos or stale module names; scripts iterating a glob that includes deleted files; the module not being installed in the environment used (`--environment` mismatch); case-sensitivity after moving configs from macOS/Windows to Linux.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

          # directory should not be treated as a failed validation.
          Puppet.notice _("No template specified. No action taken")
        end
      end

      missing_files = []
      files.each do |file|
        break if !status && !options[:continue_on_error]

        template_file = effective_template(file, compiler.environment)
        if template_file
          tmp = validate_template(template_file)
          status &&= tmp
        else
          missing_files << file
        end
      end
      if !missing_files.empty?
        raise Puppet::Error, _("One or more file(s) specified did not exist:\n%{missing_files_list}") %
                             { missing_files_list: missing_files.map { |f| "   #{f}" }.join("\n") }
      else
        # Exit with 1 if there were errors
        raise Puppet::Error, _("Errors while validating epp") unless status
      end
    end
  end

  action(:dump) do
    summary _("Outputs a dump of the internal template parse tree for debugging")
    arguments "[--format <old|pn|json>] [--pretty] { -e <source> | [<templates> ...] } "
    returns _("A dump of the resulting AST model unless there are syntax or validation errors.")
    description <<-'EOT'
      The dump action parses and validates the EPP syntax and dumps the resulting AST model
      in a human readable (but not necessarily an easy to understand) format.

      The output format can be controlled using the --format <old|pn|json> where:
      * 'old' is the default, but now deprecated format which is not API.

View on GitHub (pinned to e227c27540)