puppetlabs/puppet · error · ArgumentError
'put' requires a string 'body' argument
Error message
'put' requires a string 'body' argument
What it means
Puppet::HTTP::Client#put validates up front that the request body is a String and raises ArgumentError otherwise, before any network I/O. The API intentionally has no implicit serialization — callers must render payloads (JSON, PSON, text) to a string themselves and pair it with a matching Content-Type.
Source
Thrown at lib/puppet/http/client.rb:239
execute_streaming(request, options: options)
end
# Submits a PUT HTTP request to the given url
#
# @param [URI] url the location to submit the http request
# @param [String] body the body of the PUT request
# @param [Hash] headers merged with the default headers defined by the client. The
# `Content-Type` header is required and should correspond to the type of data passed
# as the `body` argument.
# @param [Hash] params encoded and set as the url query
# @!macro request_options
#
# @return [Puppet::HTTP::Response] the response
#
# @api public
def put(url, body, headers: {}, params: {}, options: {})
raise ArgumentError, "'put' requires a string 'body' argument" unless body.is_a?(String)
url = encode_query(url, params)
request = Net::HTTP::Put.new(url, @default_headers.merge(headers))
request.body = body
request.content_length = body.bytesize
raise ArgumentError, "'put' requires a 'content-type' header" unless request['Content-Type']
execute_streaming(request, options: options)
end
# Submits a POST HTTP request to the given url
#
# @param [URI] url the location to submit the http request
# @param [String] body the body of the POST request
# @param [Hash] headers merged with the default headers defined by the client. The
# `Content-Type` header is required and should correspond to the type of data passedView on GitHub (pinned to e227c27540)
Solutions
- Render the payload to a String before the call: body = JSON.generate(data).
- For file content, use File.read(path) so you pass the string (and set bytesize-derived length is handled internally).
- If the value may legitimately be absent, pass an empty string '' rather than nil.
Example fix
# before
client.put(url, { status: 'done' }, headers: { 'Content-Type' => 'application/json' })
# after
client.put(url, JSON.generate(status: 'done'), headers: { 'Content-Type' => 'application/json' }) Defensive patterns
Strategy: type-guard
Validate before calling
body = JSON.generate(data) unless body.is_a?(String)
client.put(url, body, headers: { 'Content-Type' => 'application/json' }) Type guard
string_body = ->(b) { b.is_a?(String) }
raise ArgumentError, 'body must be a String' unless string_body.call(body) Prevention
- Always serialize payloads explicitly (JSON.generate / to_pem / File.read).
- Never forward nil bodies; substitute '' for 'no body'.
When it happens
Trigger: client.put(url, nil, headers: { 'Content-Type' => 'text/plain' }); client.put(url, { 'key' => 'value' }, ...) with a Hash; passing an IO or template object instead of its read content.
Common situations: Migrating from Puppet::Network::HttpPool or RestClient where the library serialized for you; forgetting JSON.generate when sending a report or catalog fragment; reading a file body but passing the File object.
Related errors
- 'post' requires a string 'body' argument
- 'put' requires a 'content-type' header
- 'post' requires a string 'body' argument
- A block is required
- Could not download module: %{message}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/996eb18d46640627.
Report an issue: GitHub.