{"record":{"id":"91f946d6074e3aa8","repo":"puppetlabs/puppet","slug":"filename-91f946","errorCode":null,"errorMessage":"--- #{filename}","messagePattern":"--- #\\{filename\\}","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/puppet/face/parser.rb","lineNumber":204,"sourceCode":"      if show_filename\n        output << \"--- #{filename}\"\n      end\n      fmt = options[:format]\n      if fmt.nil? || fmt == 'old'\n        output << Puppet::Pops::Model::ModelTreeDumper.new.dump(parse_result) << \"\\n\"\n      else\n        require_relative '../../puppet/pops/pn'\n        pn = Puppet::Pops::Model::PNTransformer.transform(parse_result)\n        case fmt\n        when 'json'\n          options[:pretty] ? JSON.pretty_unparse(pn.to_data) : JSON.dump(pn.to_data)\n        else\n          pn.format(options[:pretty] ? Puppet::Pops::PN::Indent.new('  ') : nil, output)\n        end\n      end\n    rescue Puppet::ParseError => detail\n      if show_filename\n        Puppet.err(\"--- #{filename}\")\n      end\n      Puppet.err(detail.message)\n      \"\"\n    end\n  end\n\n  # @api private\n  def validate_manifest(manifest = nil)\n    env = Puppet.lookup(:current_environment)\n    loaders = Puppet::Pops::Loaders.new(env)\n\n    Puppet.override({ :loaders => loaders }, _('For puppet parser validate')) do\n      validation_environment = manifest ? env.override_with(:manifest => manifest) : env\n      validation_environment.check_for_reparse\n      validation_environment.known_resource_types.clear\n    rescue Puppet::ParseError => parse_error\n      return parse_error\n    end","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/face/parser.rb#L186-L222","documentation":"Printed during `puppet parser validate` with multiple manifests: for each file raising Puppet::ParseError, with show_filename on, a '--- <file>' header precedes the parse error message and that file's output becomes ''. Validation continues with the remaining files, so one header plus message pair appears per broken manifest.","triggerScenarios":"`puppet parser validate manifests/ 'site/*.pp'` where any file has invalid Puppet DSL: unmatched braces, bad expressions, reserved words — the EvaluatingParser#parse_file call raises Puppet::ParseError and the rescue prints the header.","commonSituations":"CI syntax gates over site/ and modules/; manifests authored for a newer or older grammar; generated manifests with template substitution bugs.","solutions":["Fix the error on the line printed after each header — it names the file and line","Iterate on a single file with `puppet parser validate <file>`","Wire `puppet parser validate` into pre-commit hooks and CI to catch manifests early"],"exampleFix":"# before (site.pp)\nnode default { notify { 'hi: } }\n\n# after\nnode default { notify { 'hi': } }","handlingStrategy":"try-catch","validationCode":"require 'puppet/pops/parser/evaluating_parser'\n\nfailed = []\nDir['**/*.pp'].each do |f|\n  begin\n    Puppet::Pops::Parser::EvaluatingParser.new.parse_file(f)\n  rescue Puppet::ParseError => e\n    warn \"--- #{f}\"\n    warn e.message\n    failed << f\n  end\nend\nexit 1 unless failed.empty?","typeGuard":null,"tryCatchPattern":"begin\n  parser.parse_file(manifest)\nrescue Puppet::ParseError => e\n  Puppet.err \"--- #{manifest}\"\n  Puppet.err e.message\n  \"\"                          # mirror the face: report and continue with other files\nend","preventionTips":["Add `puppet parser validate .` as a CI gate for modules and site manifests","Use pre-commit hooks that validate the staged .pp files"],"tags":["ruby","puppet","parser","manifest","validation","syntax","dsl"],"backgroundTag":"manifest-parse-error","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}