puppetlabs/puppet · error · TypeLoaderError

No file(s) found for import of '%{pattern}'

Error message

No file(s) found for import of '%{pattern}'

What it means

Raised by Puppet::Parser::TypeLoader#import_from_modules via raise_no_files_found when Puppet::Parser::Files.find_manifests_in_modules returns an empty file list for the import pattern. The `import` statement expands glob patterns against module manifests; zero matches means the pattern (module name or file glob) resolves to nothing in the environment, which Puppet treats as an error rather than a silent no-op.

Source

Thrown at lib/puppet/parser/type_loader.rb:103

    Puppet.debug { "importing '#{file}' in environment #{environment}" }
    parser = Puppet::Parser::ParserFactory.parser
    parser.file = file
    parser.parse
  end

  private

  def import_from_modules(pattern)
    modname, files = Puppet::Parser::Files.find_manifests_in_modules(pattern, environment)
    if files.empty?
      raise_no_files_found(pattern)
    end

    load_files(modname, files)
  end

  def raise_no_files_found(pattern)
    raise TypeLoaderError, _("No file(s) found for import of '%{pattern}'") % { pattern: pattern }
  end

  def load_files(modname, files)
    @loaded ||= {}
    loaded_asts = []
    files.reject { |file| @loaded[file] }.each do |file|
      # The squelch_parse_errors use case is for parsing for the purpose of searching
      # for information and it should not abort.
      # There is currently one user in indirector/resourcetype/parser
      #
      if Puppet.lookup(:squelch_parse_errors) { false }
        begin
          loaded_asts << parse_file(file)
        rescue => e
          # Resume from errors so that all parseable files may
          # still be parsed. Mark this file as loaded so that
          # it would not be parsed next time (handle it as if
          # it was successfully parsed).

View on GitHub (pinned to e227c27540)

Solutions

  1. Verify the module exists in the compiling environment's modulepath and contains manifests matching the pattern.
  2. Modernize: replace import with autoloaded layout — class foo::bar in foo/manifests/bar.pp is loaded automatically; delete the import statement.
  3. Fix the glob: `import 'users/[a-z]*.pp'` vs an actual filename; check case sensitivity.
  4. If the import is optional by design, guard it behind file existence checks in your wrapper tooling, since the DSL import itself cannot be made conditional.

Example fix

# before
import 'users/*.pp'   # No file(s) found for import of 'users/*.pp'

# after (autoloading - no import needed)
# modules/users/manifests/init.pp -> class users
# modules/users/manifests/admin.pp -> class users::admin
include users::admin
Defensive patterns

Strategy: validation

Validate before calling

# Ruby — probe the pattern before importing:
_mod, files = Puppet::Parser::Files.find_manifests_in_modules(pattern, env)
type_loader.import(pattern) unless files.empty?
# Shell — sanity check the glob:
#   ls modules/<mod>/manifests/**/*.pp

Try / catch

begin
  type_loader.import(pattern)
rescue Puppet::Parser::TypeLoaderError
  # optional import — skip instead of failing compilation
end

Prevention

When it happens

Trigger: `import 'users/*.pp'` when the users module has no .pp files matching; `import 'custom'` when module 'custom' is not in modulepath; `import 'foo/bar.pp'` where the file was moved/renamed; running under an environment whose modulepath differs from where the files live.

Common situations: Legacy Puppet 2.x/3.x code still using import after files were refactored into autoloaded classes; environment pinning (git branches) where a module exists in one branch but not the one being compiled; typos in glob patterns; upgrades to newer Puppet where import semantics were removed and previously-matching empty patterns now surface loudly.

Related errors


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