{"record":{"id":"e3179073b4e3cec9","repo":"puppetlabs/puppet","slug":"unsupported-facts-format","errorCode":null,"errorMessage":"Unsupported facts format","messagePattern":"Unsupported facts format","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/indirector/catalog/compiler.rb","lineNumber":128,"sourceCode":"    false\n  end\n\n  private\n\n  # @param facts [String] facts in a wire format for decoding\n  # @param format [String] a content-type string\n  # @return [Puppet::Node::Facts] facts object deserialized from supplied string\n  # @api private\n  def convert_wire_facts(facts, format)\n    case format\n    when 'pson'\n      # We unescape here because the corresponding code in Puppet::Configurer::FactHandler encodes with Puppet::Util.uri_query_encode\n      # PSON is deprecated, but continue to accept from older agents\n      Puppet::Node::Facts.convert_from('pson', CGI.unescape(facts))\n    when 'application/json'\n      Puppet::Node::Facts.convert_from('json', CGI.unescape(facts))\n    else\n      raise ArgumentError, _(\"Unsupported facts format\")\n    end\n  end\n\n  # Add any extra data necessary to the node.\n  def add_node_data(node)\n    # Merge in our server-side facts, so they can be used during compilation.\n    node.add_server_facts(@server_facts)\n  end\n\n  # Determine which checksum to use; if agent_checksum_type is not nil,\n  # use the first entry in it that is also in known_checksum_types.\n  # If no match is found, return nil.\n  def common_checksum_type(agent_checksum_type)\n    if agent_checksum_type\n      agent_checksum_types = agent_checksum_type.split('.').map(&:to_sym)\n      checksum_type = agent_checksum_types.drop_while do |type|\n        !known_checksum_types.include? type\n      end.first","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/indirector/catalog/compiler.rb#L110-L146","documentation":"convert_wire_facts in the catalog compiler only understands two wire formats for client-submitted facts: 'pson' (legacy, still accepted from older agents) and 'application/json' (the current agent format; the payload is URI-unescaped then parsed). Any other value for request.options[:facts_format] raises ArgumentError.","triggerScenarios":"Passing facts_format: 'json' (bare subtype), 'yaml', or a content type with parameters like 'application/json; charset=utf-8' — the value is matched literally against the two accepted strings.","commonSituations":"Custom clients abbreviating the MIME type to 'json'; tooling copied from the v3 REST API that used format extensions like .pson or .yaml; content-type strings copied straight from HTTP headers.","solutions":["Use exactly 'application/json' (modern) or 'pson' (legacy interop) as the facts_format value","Strip charset/parameters from content types before putting them into options","Send no facts at all if the compile does not depend on them"],"exampleFix":"# before (ruby)\nopts = { facts: facts_json, facts_format: 'json' }  # => ArgumentError\n\n# after\nopts = { facts: facts_json, facts_format: 'application/json' }","handlingStrategy":"validation","validationCode":"# ruby\nALLOWED = %w[pson application/json].freeze\nfmt = fmt.split(';').first.to_s.strip.downcase\nraise ArgumentError, \"unsupported facts format #{fmt}\" unless ALLOWED.include?(fmt)\nopts[:facts_format] = fmt","typeGuard":"def supported_facts_format?(f)\n  %w[pson application/json].include?(f)\nend","tryCatchPattern":"begin\n  Puppet::Resource::Catalog.indirection.find(key, opts)\nrescue ArgumentError => e\n  raise unless e.message.include?('facts format')\n  opts[:facts_format] = 'application/json'\n  retry\nend","preventionTips":["Use exactly 'application/json' for new code; keep 'pson' only for pre-4.0 interop","Sanitize content types (strip parameters) before putting them into options","Centralize the format constant instead of repeating the literal"],"tags":["puppet-compiler","facts","content-type","serialization"],"backgroundTag":"unsupported-content-type","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}