{"record":{"id":"7ae1b0201478799c","repo":"ruby/ruby","slug":"bad-uri-absolute-but-no-path-uri","errorCode":null,"errorMessage":"bad URI (absolute but no path): #{uri}","messagePattern":"bad URI \\(absolute but no path\\): #(.+?)","errorType":"exception","errorClass":"InvalidURIError","httpStatus":null,"severity":"error","filePath":"lib/uri/rfc2396_parser.rb","lineNumber":146,"sourceCode":"\n        # URI-reference = [ absoluteURI | relativeURI ] [ \"#\" fragment ]\n\n        # absoluteURI   = scheme \":\" ( hier_part | opaque_part )\n        # hier_part     = ( net_path | abs_path ) [ \"?\" query ]\n        # opaque_part   = uric_no_slash *uric\n\n        # abs_path      = \"/\"  path_segments\n        # net_path      = \"//\" authority [ abs_path ]\n\n        # authority     = server | reg_name\n        # server        = [ [ userinfo \"@\" ] hostport ]\n\n        if !scheme\n          raise InvalidURIError,\n            \"bad URI (absolute but no scheme): #{uri}\"\n        end\n        if !opaque && (!path && (!host && !registry))\n          raise InvalidURIError,\n            \"bad URI (absolute but no path): #{uri}\"\n        end\n\n      when @regexp[:REL_URI]\n        scheme = nil\n        opaque = nil\n\n        userinfo, host, port, registry,\n          rel_segment, abs_path, query, fragment = $~[1..-1]\n        if rel_segment && abs_path\n          path = rel_segment + abs_path\n        elsif rel_segment\n          path = rel_segment\n        elsif abs_path\n          path = abs_path\n        end\n\n        # URI-reference = [ absoluteURI | relativeURI ] [ \"#\" fragment ]","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/ruby/ruby/blob/0e5b888e1c355f3f728f2659f085820937dada48/lib/uri/rfc2396_parser.rb#L128-L164","documentation":"The RFC 2396 parser captured a scheme but found nothing after the colon — no path, no opaque part, and no host or registry. 'scheme:' alone is not an absolute URI under RFC 2396, so split raises 'bad URI (absolute but no path)'.","triggerScenarios":"URI::Parser.new.parse('http:'); parser.split('ftp:'); interpolated URIs like \"#{scheme}:#{rest}\" where rest is empty.","commonSituations":"Template-built URIs with an empty remainder; config values reduced to a bare scheme; validation code routing scheme-only strings through the legacy parser.","solutions":["Check the interpolated remainder is non-empty before parsing","Switch to the default RFC 3986 parser (URI.parse/URI()), which accepts 'http:' with an empty path","Reject scheme-only strings with a dedicated regexp and a clear domain error"],"exampleFix":"# before\nuri = URI::Parser.new.parse(\"#{scheme}:#{rest}\")   # rest = \"\"\n# InvalidURIError: bad URI (absolute but no path)\n\n# after\nraise ArgumentError, \"missing part after scheme '#{scheme}:'\" if rest.to_s.empty?\nuri = URI.parse(\"#{scheme}:#{rest}\")","handlingStrategy":"validation","validationCode":"BARE_SCHEME = /\\A[A-Za-z][A-Za-z0-9+.-]*:\\z/\ndef complete_uri?(s)\n  !BARE_SCHEME.match?(s.to_s)\nend","typeGuard":null,"tryCatchPattern":"begin\n  parser.parse(str)\nrescue URI::InvalidURIError\n  raise ArgumentError, \"URI is scheme-only, nothing after the colon: #{str}\"\nend","preventionTips":["Check interpolated URI fragments for emptiness before parsing","Prefer the default RFC 3986 parser when bare-scheme strings are legitimate","Validate scheme-only configs with a dedicated regexp and fail loudly"],"tags":["ruby","uri","rfc2396","empty-path","scheme"],"backgroundTag":"incomplete-uri","analyzedSha":"0e5b888e1c355f3f728f2659f085820937dada48","analyzedAt":"2026-08-21T14:25:43.473Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}