jnunemaker/httparty · error · ArgumentError
:basic_auth must be a hash
Error message
:basic_auth must be a hash
What it means
Request#validate raises ArgumentError ':basic_auth must be a hash' when options[:basic_auth] is truthy but does not respond to #to_hash. basic_auth is accepted as a keyword option on any verb call and must be a Hash with :username/:password (or 'username'/'password') keys; strings, arrays or auth objects from other libraries are rejected before the request runs.
Source
Thrown at lib/httparty/request.rb:419
options[:headers] ||= {}
options[:headers]['Cookie'] = cookies_hash.to_cookie_string
end
# Uses the HTTP Content-Type header to determine the format of the
# response It compares the MIME type returned to the types stored in the
# SupportedFormats hash
def format_from_mimetype(mimetype)
if mimetype && parser.respond_to?(:format_from_mimetype)
parser.format_from_mimetype(mimetype)
end
end
def validate
raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0
raise ArgumentError, 'only get, post, patch, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method)
raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].respond_to?(:to_hash)
raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth]
raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].respond_to?(:to_hash)
raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].respond_to?(:to_hash)
raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].respond_to?(:to_hash)
end
def post?
Net::HTTP::Post == http_method
end
def set_basic_auth_from_uri
if path.userinfo
username, password = path.userinfo.split(':')
options[:basic_auth] = {username: username, password: password}
@credentials_sent = true
end
end
def decompress(body, encoding)
Decompressor.new(body, encoding).decompressView on GitHub (pinned to 8f4a09e343)
Solutions
- Pass the documented Hash: `basic_auth: { username: user, password: pass }`.
- Convert string creds: `basic_auth: Hash[%w[username password].zip(creds.split(':'))]`.
- Prefer the class-level DSL `basic_auth user, pass` for static credentials.
Example fix
# before
Foo.get(url, basic_auth: 'user:pass') # String -> ArgumentError
# after
Foo.get(url, basic_auth: { username: 'user', password: 'pass' }) Defensive patterns
Strategy: validation
Validate before calling
auth = { username: user, password: pass } unless auth.respond_to?(:to_hash)
raise ArgumentError, ':basic_auth must be a hash' unless auth.respond_to?(:to_hash)
Foo.get(url, basic_auth: auth) Type guard
hash_like = ->(v) { v.respond_to?(:to_hash) } Try / catch
begin
Foo.get(url, basic_auth: auth)
rescue ArgumentError => e
raise unless e.message.include?('basic_auth')
Foo.get(url, basic_auth: { username: auth[0], password: auth[1] })
end Prevention
- Always use { username:, password: } literal shape for auth options.
- Normalize credentials at the config layer into a Hash with symbol keys.
- Prefer class-level `basic_auth user, pass` for static creds.
When it happens
Trigger: `Foo.get(url, basic_auth: 'user:pass')`, `basic_auth: [user, pass]`, or `basic_auth: SomeGem::Credentials.new` (an object without to_hash).
Common situations: Pasting 'user:pass' strings from curl examples, storing credentials as arrays/tuples in config, and adapting code from gems with different auth option shapes.
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
- only one authentication method, :basic_auth or :digest_auth
- :digest_auth must be a hash
- :headers must be a hash
- :query must be hash if using HTTP Post
- Default params must be an object which responds to #to_hash
AI-assisted analysis of jnunemaker/httparty@8f4a09e343 (2026-08-21).
Data as JSON: /api/errors/a8569a8059ef8ba2.
Report an issue: GitHub.