{"record":{"id":"80bf6fc1f48e412e","repo":"lostisland/faraday","slug":"bad-argument-expected-uri-object-or-uri-string","errorCode":null,"errorMessage":"bad argument (expected URI object or URI string)","messagePattern":"bad argument \\(expected URI object or URI string\\)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/faraday/utils.rb","lineNumber":76,"sourceCode":"      \"Basic #{value}\"\n    end\n\n    class << self\n      attr_writer :default_params_encoder\n    end\n\n    # Normalize URI() behavior across Ruby versions\n    #\n    # url - A String or URI.\n    #\n    # Returns a parsed URI.\n    def URI(url) # rubocop:disable Naming/MethodName\n      if url.respond_to?(:host)\n        url\n      elsif url.respond_to?(:to_str)\n        default_uri_parser.call(url)\n      else\n        raise ArgumentError, 'bad argument (expected URI object or URI string)'\n      end\n    end\n\n    def default_uri_parser\n      @default_uri_parser ||= Kernel.method(:URI)\n    end\n\n    def default_uri_parser=(parser)\n      @default_uri_parser = if parser.respond_to?(:call) || parser.nil?\n                              parser\n                            else\n                              parser.method(:parse)\n                            end\n    end\n\n    # Receives a String or URI and returns just\n    # the path with the query string sorted.\n    def normalize_path(url)","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/lostisland/faraday/blob/b25b1b26ccef34b1460b0267115be238ca758087/lib/faraday/utils.rb#L58-L94","documentation":"Faraday::Utils.URI normalizes URL inputs for internal use: an object responding to #host is passed through untouched (any URI-like value), an object responding to #to_str is handed to the configured URI parser (default_uri_parser, Kernel.URI unless overridden), and everything else raises ArgumentError. nil is included in 'everything else', so a nil or non-stringy URL reaching this helper is the failure.","triggerScenarios":"Passing nil, a Symbol, Integer, Hash, or Pathname where a URL is required — e.g. Faraday.new(config.base_url) when config.base_url is nil-from-missing-env-var in some paths, conn.url_prefix = 42, or middleware assigning a custom wrapper object to env[:url] that implements neither #host nor #to_str.","commonSituations":"YAML/env configuration where the URL key is misspelled so the value is nil only in certain environments; passing an options Hash instead of a URL string; custom URI value objects that lack #host; Addressable::URI works (responds to #host) but a Struct wrapping a URI does not.","solutions":["Coerce to a String or a real URI before passing: URI.parse(str) or str.to_s.","Nil-guard configuration at load time and fail loudly with a clear message: raise \"base_url missing\" if base_url.nil?, or supply a default.","For custom URI wrapper classes, implement #host (marker of URI-ness) or #to_str so Faraday can use them.","If you configured Faraday.default_uri_parser, verify it still returns URI objects — custom parsers changing the contract also surface here."],"exampleFix":"# before\nbase_url = ENV['API_URL']          # nil when unset\nconn = Faraday.new(base_url)\n# later request => ArgumentError: bad argument (expected URI object or URI string)\n\n# after\nbase_url = ENV.fetch('API_URL') { 'https://api.example.com' }\nconn = Faraday.new(URI.parse(base_url))","handlingStrategy":"type-guard","validationCode":"url = url.to_s\nurl = ENV.fetch('API_URL') { 'https://api.example.com' } if url.empty?\nconn = Faraday.new(URI.parse(url))","typeGuard":"def uri_like?(url)\n  url.respond_to?(:host) || url.respond_to?(:to_str)\nend","tryCatchPattern":"begin\n  Faraday.new(url)\nrescue ArgumentError => e\n  raise unless e.message.include?('expected URI object')\n  Faraday.new(url.to_s) # coerce and retry once\nend","preventionTips":["Validate URL config at boot with URI.parse and a presence check; fail fast with a named error, not mid-request.","Use ENV.fetch with a default for URL config instead of ENV[...] which yields nil silently.","Custom URI wrapper classes must respond to #host or #to_str to pass Faraday's normalization."],"tags":["ruby","faraday","url","uri-parsing","argumenterror","configuration"],"backgroundTag":"invalid-url-argument","analyzedSha":"b25b1b26ccef34b1460b0267115be238ca758087","analyzedAt":"2026-08-21T19:43:20.220Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}