jnunemaker/httparty · error · ArgumentError
bad argument (expected #{uri_adapter} object or URI string)
Error message
bad argument (expected #{uri_adapter} object or URI string) What it means
Request#path= raises ArgumentError 'bad argument (expected URI object or URI string)' when the path passed to a verb method is neither an instance of the configured uri_adapter nor convertible with String.try_convert. Every HTTParty verb (get/post/put/...) funnels its path through this setter, so passing nil, an Integer, a Symbol, or objects like Pathname that do not define to_str fail here before any connection is opened.
Source
Thrown at lib/httparty/request.rb:87
default_params: {},
follow_redirects: true,
parser: Parser,
uri_adapter: URI,
connection_adapter: ConnectionAdapter
}.merge(o)
self.path = path
set_basic_auth_from_uri
end
def path=(uri)
uri_adapter = options[:uri_adapter]
@path = if uri.is_a?(uri_adapter)
uri
elsif String.try_convert(uri)
uri_adapter.parse(uri).normalize
else
raise ArgumentError,
"bad argument (expected #{uri_adapter} object or URI string)"
end
end
def request_uri(uri)
if uri.respond_to? :request_uri
uri.request_uri
else
uri.path
end
end
def uri
if redirect && path.relative? && path.path[0] != '/'
last_uri_host = @last_uri.path.gsub(/[^\/]+$/, '')
path.path = "/#{path.path}" if last_uri_host[-1] != '/'
path.path = "#{last_uri_host}#{path.path}"View on GitHub (pinned to 8f4a09e343)
Solutions
- Coerce to String at the call site: `Foo.get(url.to_s)` or `Foo.get(url&.to_s)`.
- Fail fast on nil upstream: `raise ArgumentError, 'url missing' if url.nil?` before building the request.
- When passing Addressable objects, configure `uri_adapter Addressable::URI` on the class.
Example fix
# before
url = ENV['ENDPOINT'] # nil when unset
Foo.get(url) # ArgumentError: bad argument
# after
url = ENV.fetch('ENDPOINT')
Foo.get(url) Defensive patterns
Strategy: validation
Validate before calling
url = ENV.fetch('ENDPOINT')
raise ArgumentError, "path must be a String or #{URI}, got #{url.class}" unless url.is_a?(String) || url.is_a?(URI)
Foo.get(url) Type guard
valid_path = ->(p) { p.is_a?(String) || p.is_a?(URI) } Try / catch
begin
Foo.get(path)
rescue ArgumentError => e
raise unless e.message.include?('bad argument')
raise ArgumentError, "URL was #{path.inspect} — check the variable feeding this call"
end Prevention
- Use ENV.fetch (not ENV[...]) for URL config so nil fails early with a clear message.
- Call .to_s on Pathname/Addressable values before passing them in.
- Assert URL presence in service constructors, not at request time.
When it happens
Trigger: `Foo.get(nil)` (usually an interpolated variable that came back nil), `Foo.get(42)`, `Foo.get(:show)`, `Foo.get(Pathname.new('/tmp/url.txt'))`, or `Foo.get(['http://x'])`. Passing an Addressable::URI while uri_adapter is the default URI also lands here.
Common situations: URLs built from ENV vars, DB fields or ERB templates that are nil in some environments, Pathname or URI::Generic objects leaking in from file-handling code, and Addressable objects passed to a client configured with the default URI adapter.
Related errors
- The URI adapter should respond to #parse
- uri must be a #{uri_adapter}, not a #{uri.class}
- Default params must be an object which responds to #to_hash
- Headers must be an object which responds to #to_hash
- Cookies must be an object which responds to #to_hash
AI-assisted analysis of jnunemaker/httparty@8f4a09e343 (2026-08-21).
Data as JSON: /api/errors/7f5bd994132f51ab.
Report an issue: GitHub.