puppetlabs/puppet · error · Puppet::Error

manifest of environment '#{@environment.name}' appoints '#{f

Error message

manifest of environment '#{@environment.name}' appoints '#{file}'. It does not exist

What it means

Companion guard to the directory check in Loaders#load_environment: the manifest path from environment.conf is neither NO_MANIFEST, nor a directory, nor an existing file, so File.exist?(file) is false and Puppet::Error is raised. The appointed manifest file simply is not on disk at that path.

Source

Thrown at lib/puppet/pops/loaders.rb:302

  # @return [Model::Program] The manifest parsed into a model object
  def load_main_manifest
    parser = Parser::EvaluatingParser.singleton
    parsed_code = Puppet[:code]
    program = if parsed_code != ""
                parser.parse_string(parsed_code, 'unknown-source-location')
              else
                file = @environment.manifest

                # if the manifest file is a reference to a directory, parse and
                # combine all .pp files in that directory
                if file == Puppet::Node::Environment::NO_MANIFEST
                  nil
                elsif File.directory?(file)
                  raise Puppet::Error, "manifest of environment '#{@environment.name}' appoints directory '#{file}'. It must be a file"
                elsif File.exist?(file)
                  parser.parse_file(file)
                else
                  raise Puppet::Error, "manifest of environment '#{@environment.name}' appoints '#{file}'. It does not exist"
                end
              end
    instantiate_definitions(program, public_environment_loader) unless program.nil?
    program
  rescue Puppet::ParseErrorWithIssue => detail
    detail.environment = @environment.name
    raise
  rescue => detail
    msg = _('Could not parse for environment %{env}: %{detail}') % { env: @environment, detail: detail }
    error = Puppet::Error.new(msg)
    error.set_backtrace(detail.backtrace)
    raise error
  end

  # Add 4.x definitions found in the given program to the given loader.
  def instantiate_definitions(program, loader)
    program.definitions.each { |d| instantiate_definition(d, loader) }
    nil

View on GitHub (pinned to e227c27540)

Solutions

  1. Create the missing file at the exact path shown in the message.
  2. Fix the path in environment.conf — relative paths resolve against the environment root, so verify with `ls environments/<env>/<path>`.
  3. If the environment has no manifest, set the manifest setting to no_manifest explicitly.

Example fix

# environment.conf: manifest = manifests/site.pp
# before: environments/production/manifests/ is empty or missing site.pp
# after: create environments/production/manifests/site.pp containing at minimum:
#   node default { }
Defensive patterns

Strategy: validation

Validate before calling

# Ensure the appointed manifest exists before deploy
env_root = 'environments/production'
manifest = File.foreach(File.join(env_root, 'environment.conf'))
                    .map { |l| l[/^\s*manifest\s*=\s*(\S+)/, 1] }.compact.first
if manifest && manifest != 'no_manifest'
  path = File.expand_path(manifest, env_root)
  raise "manifest '#{path}' does not exist" unless File.exist?(path)
end

Prevention

When it happens

Trigger: environment.conf `manifest = manifests/site.pp` but the file was never created, was deleted, or the path is relative to a different base than expected; typo in the path; deploy pipeline skipped copying manifests.

Common situations: Control repo deploy that copied hiera data but not manifests; branch where site.pp was moved; CI validating an environment before manifests are rendered.

Related errors


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