puppetlabs/puppet · error · ArgumentError

Unknown arguments: %{args}

Error message

Unknown arguments: %{args}

What it means

Puppet::Network::HTTP::Request.from_hash builds a Request struct from a hash and rejects any key that is not one of its members: headers, params, method, path, routing_path, client_cert, body. Unknown keys raise ArgumentError listing the inspected names, catching typos and stale field names before a malformed request object exists.

Source

Thrown at lib/puppet/network/http/request.rb:22

# parameter to the current Handler subclass. Puppetserver implements its own
# Handler
# https://github.com/puppetlabs/puppetserver/blob/8.3.0/src/ruby/puppetserver-lib/puppet/server/network/http/handler.rb#L9
# and the Request object is passed to its Handler#body method
# https://github.com/puppetlabs/puppetserver/blob/8.3.0/src/ruby/puppetserver-lib/puppet/server/network/http/handler.rb#L36
Puppet::Network::HTTP::Request = Struct.new(:headers, :params, :method, :path, :routing_path, :client_cert, :body) do # rubocop:disable Lint/StructNewOverride
  def self.from_hash(hash)
    symbol_members = members.collect(&:intern)
    unknown = hash.keys - symbol_members
    if unknown.empty?
      new(hash[:headers] || {},
          hash[:params] || {},
          hash[:method] || "GET",
          hash[:path],
          hash[:routing_path] || hash[:path],
          hash[:client_cert],
          hash[:body])
    else
      raise ArgumentError, _("Unknown arguments: %{args}") % { args: unknown.collect(&:inspect).join(', ') }
    end
  end

  def route_into(prefix)
    self.class.new(headers, params, method, path, routing_path.sub(prefix, ''), client_cert, body)
  end

  def formatter
    header = headers['content-type']
    if header
      header.gsub!(/\s*;.*$/, '') # strip any charset
      format = Puppet::Network::FormatHandler.mime(header)

      return format if valid_network_format?(format)

      # TRANSLATORS "mime-type" is a keyword and should not be translated
      raise Puppet::Network::HTTP::Error::HTTPUnsupportedMediaTypeError.new(
        _("Client sent a mime-type (%{header}) that doesn't correspond to a format we support") % { header: headers['content-type'] },

View on GitHub (pinned to e227c27540)

Solutions

  1. Whitelist keys before calling: hash = hash.slice(:headers, :params, :method, :path, :routing_path, :client_cert, :body)
  2. Rename stale keys to the current members listed in the error message
  3. Update the third-party adapter/handler gem to a version matching your Puppet version

Example fix

# before
Puppet::Network::HTTP::Request.from_hash(params.merge(peer_ip: ip))

# after
Puppet::Network::HTTP::Request.from_hash(
  params.slice(:headers, :params, :method, :path, :routing_path, :client_cert, :body)
)
Defensive patterns

Strategy: validation

Validate before calling

REQUEST_MEMBERS = %i[headers params method path routing_path client_cert body].freeze

request_hash = request_hash.select { |k, _| REQUEST_MEMBERS.include?(k) }
Puppet::Network::HTTP::Request.from_hash(request_hash)

Prevention

When it happens

Trigger: Passing a hash containing extra keys such as peer_ip or remote_address; building requests in custom WEBrick/Rack adapters whose dictionaries were written for an older Puppet's Request; merging foreign hashes into the request hash before calling from_hash.

Common situations: Upgrading Puppet where Request gained members (routing_path, client_cert) and adapter code drifted; third-party rack handlers not yet updated for the new Puppet; typo'd keys (':header' instead of ':headers').

Related errors


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