jnunemaker/httparty · error · ArgumentError
uri must be a #{uri_adapter}, not a #{uri.class}
Error message
uri must be a #{uri_adapter}, not a #{uri.class} What it means
ConnectionAdapter's constructor raises ArgumentError when the uri argument is not an instance of the configured uri_adapter class (options[:uri_adapter], defaulting to URI). HTTParty parses request paths with the same adapter, so in the normal request flow the types line up; this error appears when a custom connection_adapter builds its own adapter or someone instantiates HTTParty::ConnectionAdapter directly and passes, say, an Addressable::URI while the adapter default is URI (or the reverse).
Source
Thrown at lib/httparty/connection_adapter.rb:93
verify_peer: true
}
# Public
def self.call(uri, options)
new(uri, options).connection
end
def self.default_cert_store
@default_cert_store ||= OpenSSL::X509::Store.new.tap do |cert_store|
cert_store.set_default_paths
end
end
attr_reader :uri, :options
def initialize(uri, options = {})
uri_adapter = options[:uri_adapter] || URI
raise ArgumentError, "uri must be a #{uri_adapter}, not a #{uri.class}" unless uri.is_a? uri_adapter
@uri = uri
@options = OPTION_DEFAULTS.merge(options)
end
def connection
host = clean_host(uri.host)
port = uri.port || (uri.scheme == 'https' ? 443 : 80)
if options.key?(:http_proxyaddr)
http = Net::HTTP.new(
host,
port,
options[:http_proxyaddr],
options[:http_proxyport],
options[:http_proxyuser],
options[:http_proxypass]
)
elseView on GitHub (pinned to 8f4a09e343)
Solutions
- Pass the same URI class the request was parsed with: use options[:uri_adapter] when building the adapter.
- Re-parse before constructing: `HTTParty::ConnectionAdapter.new(uri_adapter.parse(uri.to_s), uri_adapter: uri_adapter)`.
- Standardize the whole client on one adapter by setting `uri_adapter Addressable::URI` (or default URI) at the class level.
Example fix
# before
adapter = HTTParty::ConnectionAdapter.new(
Addressable::URI.parse('http://example.com/'),
{}
) # default uri_adapter is URI -> ArgumentError
# after
adapter = HTTParty::ConnectionAdapter.new(
Addressable::URI.parse('http://example.com/'),
uri_adapter: Addressable::URI
) Defensive patterns
Strategy: validation
Validate before calling
adapter_class = options[:uri_adapter] || URI uri = adapter_class.parse(uri.to_s) unless uri.is_a?(adapter_class) HTTParty::ConnectionAdapter.new(uri, options)
Type guard
matches_adapter = ->(uri, adapter = URI) { uri.is_a?(adapter) } Try / catch
begin HTTParty::ConnectionAdapter.new(uri, options) rescue ArgumentError => e raise if options[:uri_adapter] HTTParty::ConnectionAdapter.new(URI.parse(uri.to_s), options) end
Prevention
- In custom connection adapters, always read options[:uri_adapter] instead of hardcoding a URI class.
- Standardize the client on one uri_adapter end to end.
- Re-parse foreign URI objects with the active adapter before use.
When it happens
Trigger: `HTTParty::ConnectionAdapter.new(Addressable::URI.parse('http://x/'), {})` (default adapter is URI); a custom connection_adapter proc that re-wraps options with a different uri_adapter than the one used to parse the path; passing URI::HTTPS when uri_adapter Addressable::URI is configured.
Common situations: Writing custom connection adapters for instrumentation or connection pooling, mixing URI and Addressable handling across code paths after adopting uri_adapter, and test harnesses that construct the adapter directly with the wrong URI class.
Related errors
- The URI adapter should respond to #parse
- bad argument (expected #{uri_adapter} object or URI string)
- 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/3c1c888a773efa07.
Report an issue: GitHub.