{"record":{"id":"d67095f4dad1ff5d","repo":"jnunemaker/httparty","slug":"new-uri-must-be-http-https-or-generic","errorCode":null,"errorMessage":"'#{new_uri}' Must be HTTP, HTTPS or Generic","messagePattern":"'#(.+?)' Must be HTTP, HTTPS or Generic","errorType":"exception","errorClass":"HTTParty::UnsupportedURIScheme","httpStatus":null,"severity":"error","filePath":"lib/httparty/request.rb","lineNumber":124,"sourceCode":"      end\n\n      if path.relative? && path.host\n        new_uri = options[:uri_adapter].parse(\"#{@last_uri.scheme}:#{path}\").normalize\n      elsif path.relative?\n        new_uri = options[:uri_adapter].parse(\"#{base_uri}#{path}\").normalize\n      else\n        new_uri = path.clone\n      end\n\n      validate_uri_safety!(new_uri) unless redirect\n\n      # avoid double query string on redirects [#12]\n      unless redirect\n        new_uri.query = query_string(new_uri)\n      end\n\n      unless SupportedURISchemes.include? new_uri.scheme\n        raise UnsupportedURIScheme, \"'#{new_uri}' Must be HTTP, HTTPS or Generic\"\n      end\n\n      @last_uri = new_uri\n    end\n\n    def base_uri\n      if redirect\n        base_uri = \"#{@last_uri.scheme}://#{@last_uri.host}\"\n        base_uri = \"#{base_uri}:#{@last_uri.port}\" if @last_uri.port != 80\n        base_uri\n      else\n        options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri])\n      end\n    end\n\n    def format\n      options[:format] || (format_from_mimetype(last_response['content-type']) if last_response)\n    end","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/jnunemaker/httparty/blob/8f4a09e343b94de9f934f388028ca97620c9b378/lib/httparty/request.rb#L106-L142","documentation":"HTTParty raises UnsupportedURIScheme when the fully-built request URI's scheme is not in SupportedURISchemes (['http', 'https', 'webcal', nil] — nil meaning a scheme-less generic/relative URI). The check happens after the query string is attached, on every non-redirect request. The message names HTTP, HTTPS and Generic; webcal is also accepted. ftp://, file://, data:// and other schemes are rejected before any socket is opened.","triggerScenarios":"`Foo.get('ftp://files.example.com/data.csv')`, `base_uri 'file:///var/www'`, a response Location header pointing at a non-HTTP scheme while following redirects, or a URI built by joining a base_uri like 'example.com' with a path that resolves to an unexpected scheme.","commonSituations":"Feeds discovered from RSS/webcal links, config-driven base_uri values that accidentally include a scheme prefix like 'ftp://' or 'socket://', and tests stubbing URLs with fake schemes.","solutions":["Use http:// or https:// for the base_uri and absolute paths.","For webcal endpoints, keep the webcal scheme (it is supported) or convert it to http(s) explicitly.","Download ftp/file resources with Net::FTP/File.read instead of HTTParty."],"exampleFix":"# before\nclass Files\n  include HTTParty\n  base_uri 'ftp://files.example.com'\nend\nFiles.get('/data.csv')   # UnsupportedURIScheme\n\n# after\nbase_uri 'https://files.example.com'","handlingStrategy":"validation","validationCode":"uri = URI.parse(url.to_s)\nunless %w[http https webcal].include?(uri.scheme) || uri.scheme.nil?\n  raise HTTParty::UnsupportedURIScheme, \"#{uri.scheme} not supported\"\nend\nFoo.get(uri)","typeGuard":"supported_scheme = ->(u) { scheme = URI.parse(u.to_s).scheme; scheme.nil? || %w[http https webcal].include?(scheme) }","tryCatchPattern":"begin\n  Foo.get(url)\nrescue HTTParty::UnsupportedURIScheme\n  raise ArgumentError, \"only http/https (webcal) targets are fetchable: #{url}\"\nend","preventionTips":["Validate scheme at config load for base_uri values.","Use Net::FTP/File for non-HTTP resources.","Normalize discovered links (feeds, webhooks) to https before passing them to httparty."],"tags":["ruby","httparty","uri","scheme","validation"],"backgroundTag":"unsupported-uri-scheme","analyzedSha":"8f4a09e343b94de9f934f388028ca97620c9b378","analyzedAt":"2026-08-21T19:30:42.003Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}