{"record":{"id":"f9b4afc0cb5b117e","repo":"ruby/ruby","slug":"uri-scheme-is-invalid-uri-scheme-inspect","errorCode":null,"errorMessage":"uri scheme is invalid: #{uri.scheme.inspect}","messagePattern":"uri scheme is invalid: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/rubygems/remote_fetcher.rb","lineNumber":259,"sourceCode":"      error_detail = custom_error || response.message\n      raise FetchError.new(\"Bad response #{error_detail} #{response.code}\", uri)\n    end\n  end\n\n  alias_method :fetch_https, :fetch_http\n\n  ##\n  # Downloads +uri+ and returns it as a String.\n\n  def fetch_path(uri, mtime = nil, head = false)\n    uri = Gem::Uri.new uri\n\n    method = {\n      \"http\" => \"fetch_http\",\n      \"https\" => \"fetch_http\",\n      \"s3\" => \"fetch_s3\",\n      \"file\" => \"fetch_file\",\n    }.fetch(uri.scheme) { raise ArgumentError, \"uri scheme is invalid: #{uri.scheme.inspect}\" }\n\n    data = send method, uri, mtime, head\n\n    if data && !head && uri.to_s.end_with?(\".gz\")\n      begin\n        data = Gem::Util.gunzip data\n      rescue Zlib::GzipFile::Error\n        raise FetchError.new(\"server did not return a valid file\", uri)\n      end\n    end\n\n    data\n  rescue Gem::Timeout::Error, IOError, SocketError, SystemCallError,\n         *(OpenSSL::SSL::SSLError if Gem::HAVE_OPENSSL) => e\n    raise FetchError.new(\"#{e.class}: #{e}\", uri)\n  end\n\n  def fetch_s3(uri, mtime = nil, head = false)","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/ruby/ruby/blob/0e5b888e1c355f3f728f2659f085820937dada48/lib/rubygems/remote_fetcher.rb#L241-L277","documentation":"Gem::RemoteFetcher#fetch_path dispatches on the URI scheme to a concrete fetcher: http/https map to fetch_http, s3 to fetch_s3, and file to fetch_file. Any other scheme - including nil, which is what a scheme-less string like \"/tmp/specs.4.8.gz\" parses to - raises ArgumentError with the inspected scheme. The error is raised by Hash#fetch's default block, so it fires before any download attempt.","triggerScenarios":"Gem::RemoteFetcher.fetcher.fetch_path('ftp://host/file') or fetch_path('/local/path/specs.4.8.gz') (nil scheme). Also hit indirectly by gem commands (gem fetch, gem spec, dependency resolution) when a configured source or spec URI carries a non-http/https/s3/file scheme.","commonSituations":"Passing a plain filesystem path string where a file:// URI is required; a source left in `gem sources -l` with a bad protocol; tooling that builds URIs by string concatenation and drops the scheme; using fetch_path on git: or ssh: URIs.","solutions":["Pass a proper URI: use http:// or https:// for remote files","Prefix local paths with file:// (e.g. URI('file:///tmp/specs.4.8.gz')) so the scheme is 'file'","Audit `gem sources -l` and ~/.gemrc for entries whose scheme is not http/https and remove them with `gem sources -r`","For s3, keep the s3:// scheme and configure credentials via the standard s3 env vars RubyGems honors"],"exampleFix":"# before\nfetcher.fetch_path(\"/var/gem_mirror/specs.4.8.gz\")\n\n# after\nfetcher.fetch_path(URI(\"file:///var/gem_mirror/specs.4.8.gz\"))","handlingStrategy":"validation","validationCode":"uri = Gem::Uri.new(source)\nraise ArgumentError, \"scheme must be http/https/s3/file, got #{uri.scheme.inspect}\" unless %w[http https s3 file].include?(uri.scheme)\nfetcher.fetch_path(uri)","typeGuard":null,"tryCatchPattern":"begin\n  fetcher.fetch_path(uri)\nrescue ArgumentError => e\n  # distinguish scheme errors (message contains 'uri scheme is invalid') from other argument errors\n  raise if !e.message.include?('uri scheme is invalid')\n  warn \"skipping unsupported source #{uri}\" and nil\nend","preventionTips":["Always pass URI objects or strings with an explicit scheme; never bare filesystem paths","Use file:// prefixed URIs for local mirror files","Centralize source URL construction so scheme validation happens in one place"],"tags":["rubygems","uri","scheme","fetch","remote-fetcher"],"backgroundTag":"unsupported-uri-scheme","analyzedSha":"0e5b888e1c355f3f728f2659f085820937dada48","analyzedAt":"2026-08-21T14:25:43.473Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}