{"record":{"id":"3c1c888a773efa07","repo":"jnunemaker/httparty","slug":"uri-must-be-a-uri-adapter-not-a-uri-class","errorCode":null,"errorMessage":"uri must be a #{uri_adapter}, not a #{uri.class}","messagePattern":"uri must be a #(.+?), not a #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/httparty/connection_adapter.rb","lineNumber":93,"sourceCode":"      verify_peer: true\n    }\n\n    # Public\n    def self.call(uri, options)\n      new(uri, options).connection\n    end\n\n    def self.default_cert_store\n      @default_cert_store ||= OpenSSL::X509::Store.new.tap do |cert_store|\n        cert_store.set_default_paths\n      end\n    end\n\n    attr_reader :uri, :options\n\n    def initialize(uri, options = {})\n      uri_adapter = options[:uri_adapter] || URI\n      raise ArgumentError, \"uri must be a #{uri_adapter}, not a #{uri.class}\" unless uri.is_a? uri_adapter\n\n      @uri = uri\n      @options = OPTION_DEFAULTS.merge(options)\n    end\n\n    def connection\n      host = clean_host(uri.host)\n      port = uri.port || (uri.scheme == 'https' ? 443 : 80)\n      if options.key?(:http_proxyaddr)\n        http = Net::HTTP.new(\n          host,\n          port,\n          options[:http_proxyaddr],\n          options[:http_proxyport],\n          options[:http_proxyuser],\n          options[:http_proxypass]\n        )\n      else","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/jnunemaker/httparty/blob/8f4a09e343b94de9f934f388028ca97620c9b378/lib/httparty/connection_adapter.rb#L75-L111","documentation":"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).","triggerScenarios":"`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.","commonSituations":"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.","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."],"exampleFix":"# before\nadapter = HTTParty::ConnectionAdapter.new(\n  Addressable::URI.parse('http://example.com/'),\n  {}\n)  # default uri_adapter is URI -> ArgumentError\n\n# after\nadapter = HTTParty::ConnectionAdapter.new(\n  Addressable::URI.parse('http://example.com/'),\n  uri_adapter: Addressable::URI\n)","handlingStrategy":"validation","validationCode":"adapter_class = options[:uri_adapter] || URI\nuri = adapter_class.parse(uri.to_s) unless uri.is_a?(adapter_class)\nHTTParty::ConnectionAdapter.new(uri, options)","typeGuard":"matches_adapter = ->(uri, adapter = URI) { uri.is_a?(adapter) }","tryCatchPattern":"begin\n  HTTParty::ConnectionAdapter.new(uri, options)\nrescue ArgumentError => e\n  raise if options[:uri_adapter]\n  HTTParty::ConnectionAdapter.new(URI.parse(uri.to_s), options)\nend","preventionTips":["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."],"tags":["ruby","httparty","validation","argument-error","uri","connection-adapter"],"backgroundTag":"uri-type-mismatch","analyzedSha":"8f4a09e343b94de9f934f388028ca97620c9b378","analyzedAt":"2026-08-21T19:30:42.003Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}