jnunemaker/httparty · error · ArgumentError
Cookies must be an object which responds to #to_hash
Error message
Cookies must be an object which responds to #to_hash
What it means
The class-level DSL method `cookies` raises ArgumentError unless its argument responds to #to_hash. The value is handed to default_cookies.add_cookies, which merges it into a CookieHash applied to every request, so only Hash-like input is accepted. Note that a CookieHash or a plain Hash both work because both respond to to_hash.
Source
Thrown at lib/httparty.rb:252
# Allows setting HTTP headers to be used for each request.
#
# class Foo
# include HTTParty
# headers 'Accept' => 'text/html'
# end
def headers(h = nil)
if h
raise ArgumentError, 'Headers must be an object which responds to #to_hash' unless h.respond_to?(:to_hash)
default_options[:headers] ||= {}
default_options[:headers].merge!(h.to_hash)
else
default_options[:headers] || {}
end
end
def cookies(h = {})
raise ArgumentError, 'Cookies must be an object which responds to #to_hash' unless h.respond_to?(:to_hash)
default_cookies.add_cookies(h)
end
# Proceed to the location header when an HTTP response dictates a redirect.
# Redirects are always followed by default.
#
# @example
# class Foo
# include HTTParty
# base_uri 'http://google.com'
# follow_redirects true
# end
def follow_redirects(value = true)
default_options[:follow_redirects] = value
end
# Allows setting the format with which to parse.
# Must be one of the allowed formats ie: json, xmlView on GitHub (pinned to 8f4a09e343)
Solutions
- Pass name/value pairs as a Hash: `cookies sessionid: 'abc123'`.
- Convert a raw cookie string: `cookies Hash[raw.split('; ').map { |c| c.split('=', 2) }]`.
- Keep cookies from a prior response: assign `cookies response.headers['Set-Cookie']` only after parsing it, or use the cookie_hash from the response object.
Example fix
# before cookies 'sessionid=abc123; theme=dark' # String -> ArgumentError # after cookies 'sessionid' => 'abc123', 'theme' => 'dark'
Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, 'cookies must be a Hash' unless jar.respond_to?(:to_hash) cookies jar.to_hash
Type guard
hash_like = ->(v) { v.respond_to?(:to_hash) } Try / catch
begin
cookies jar
rescue ArgumentError
raise ConfigError, 'pass cookies as { "name" => "value" }, not a Cookie header string'
end Prevention
- Parse Set-Cookie strings before replaying them.
- Store cookie jars as plain Hashes in config.
- Remember HTTParty merges and re-serializes cookies itself; feed it name/value pairs.
When it happens
Trigger: `cookies 'sessionid=abc123'` (raw Cookie-header string) inside a class that includes HTTParty, or `cookies nil`, `cookies [:a, :b]` at class level. Distinct from the per-request `get url, cookies: { ... }` option, which flows through the same guard when merged.
Common situations: Developers pasting a browser Cookie header string from devtools, loading cookie jars from JSON/YAML without parsing, and assuming Set-Cookie strings can be replayed directly.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- Default params must be an object which responds to #to_hash
- Headers must be an object which responds to #to_hash
- The URI adapter should respond to #parse
- #{ timeout_type } must be an integer or float
- '#{format.inspect}' Must be one of: #{supported_format_names
AI-assisted analysis of jnunemaker/httparty@8f4a09e343 (2026-08-21).
Data as JSON: /api/errors/4fc37c12e9837003.
Report an issue: GitHub.