{"record":{"id":"7698e7985ca99814","repo":"puppetlabs/puppet","slug":"path-detail-message","errorCode":null,"errorMessage":"#{path}: #{detail.message}","messagePattern":"#\\{path\\}: #\\{detail\\.message\\}","errorType":"exception","errorClass":"Puppet::Util::YamlLoadError","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/yaml.rb","lineNumber":38,"sourceCode":"  #\n  # Attempting to deserialize other classes will raise an YamlLoadError\n  # exception unless they are specified in the array of *allowed_classes*.\n  # @param [String] yaml The yaml content to parse.\n  # @param [Array] allowed_classes Additional list of classes that can be deserialized.\n  # @param [String] filename The filename to load from, used if an exception is raised.\n  # @raise [YamlLoadException] If deserialization fails.\n  # @return The parsed YAML, which can be Hash, Array or scalar types.\n  def self.safe_load(yaml, allowed_classes = [], filename = nil)\n    if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0')\n      data = YAML.safe_load(yaml, permitted_classes: allowed_classes, aliases: true, filename: filename)\n    else\n      data = YAML.safe_load(yaml, allowed_classes, [], true, filename)\n    end\n    data = false if data.nil?\n    data\n  rescue ::Psych::DisallowedClass => detail\n    path = filename ? \"(#{filename})\" : \"(<unknown>)\"\n    raise YamlLoadError.new(\"#{path}: #{detail.message}\", detail)\n  rescue *YamlLoadExceptions => detail\n    raise YamlLoadError.new(detail.message, detail)\n  end\n\n  # Safely load the content from a file as YAML.\n  #\n  # @see Puppet::Util::Yaml.safe_load\n  def self.safe_load_file(filename, allowed_classes = [])\n    yaml = Puppet::FileSystem.read(filename, :encoding => 'bom|utf-8')\n    safe_load(yaml, allowed_classes, filename)\n  end\n\n  # Safely load the content from a file as YAML if\n  # contents are in valid format. This method does not\n  # raise error but returns `nil` when invalid file is\n  # given.\n  def self.safe_load_file_if_valid(filename, allowed_classes = [])\n    safe_load_file(filename, allowed_classes)","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/yaml.rb#L20-L56","documentation":"Puppet::Util::Yaml.safe_load wraps Psych.safe_load; when the document instantiates a class not listed in allowed_classes, Psych raises ::Psych::DisallowedClass and puppet re-raises it as YamlLoadError, prefixing the message with the filename (or (<unknown>)) and keeping the original as cause. Aliases are enabled (aliases: true), so anchors/aliases are fine — the guard is specifically about class tags.","triggerScenarios":"Loading YAML containing !ruby/symbol, !ruby/object, !ruby/hash or similar tags while allowed_classes is empty (the default for safe_load_file callers); files written with unsafe Psych.dump on rich objects and later read through safe_load.","commonSituations":"State/cache files hand-edited or produced by another tool and read by puppet's safe_load_file; Psych 4's safe-by-default behavior surfacing after a Ruby upgrade; YAML exchanged between components where one side serializes rich objects.","solutions":["Pass the classes you actually need: Puppet::Util::Yaml.safe_load_file(path, [Symbol]) (add Date etc. as required — the error names the rejected class)","Regenerate the offending file from plain data: hashes, arrays, strings, integers only","If you control the writer, stop emitting ruby tags — call to_yaml on plain data instead of dumping objects","Use the filename prefix in the message to identify which file is poisoned when several are loaded"],"exampleFix":"# before\nPuppet::Util::Yaml.safe_load_file('/etc/puppet/extra.yaml')\n# YamlLoadError: (/etc/puppet/extra.yaml): Tried to load unspecified class: Symbol\n\n# after\nPuppet::Util::Yaml.safe_load_file('/etc/puppet/extra.yaml', [Symbol])","handlingStrategy":"validation","validationCode":"text = File.read(path)\nif text.match?(/^.*!ruby\\//)\n  # document contains class tags; decide allowed classes up front\nend\nPuppet::Util::Yaml.safe_load(text, [Symbol], path)","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::Util::Yaml.safe_load_file(path, allowed)\nrescue Puppet::Util::YamlLoadError => e\n  # e.cause is the Psych::DisallowedClass naming the rejected class\n  raise \"untrusted YAML in #{path}: #{e.message}\"\nend","preventionTips":["Serialize plain data (Hash/Array/String/Integer) — never Psych.dump objects that must round-trip through safe_load","Pass the exact allowed_classes list you need ([Symbol] covers most puppet data)","Prefer writing YAML with to_yaml on plain structures so no ruby tags ever appear"],"tags":["yaml","psych","serialization","puppet"],"backgroundTag":"yaml-unsafe-class-rejected","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}