{"record":{"id":"4a2241d86a6496f5","repo":"ruby/ruby","slug":"relative-uri-oth","errorCode":null,"errorMessage":"relative URI: #{oth}","messagePattern":"relative URI: #(.+?)","errorType":"exception","errorClass":"BadURIError","httpStatus":null,"severity":"error","filePath":"lib/uri/generic.rb","lineNumber":1225,"sourceCode":"        else\n          return tmp\n        end\n      end\n\n      return '../' * src_path.size + tmp\n    end\n    private :route_from_path\n    # :startdoc:\n\n    # :stopdoc:\n    def route_from0(oth)\n      oth = parser.__send__(:convert_to_uri, oth)\n      if self.relative?\n        raise BadURIError,\n          \"relative URI: #{self}\"\n      end\n      if oth.relative?\n        raise BadURIError,\n          \"relative URI: #{oth}\"\n      end\n\n      if self.scheme != oth.scheme\n        return self, self.dup\n      end\n      rel = URI::Generic.new(nil, # it is relative URI\n                             self.userinfo, self.host, self.port,\n                             nil, self.path, self.opaque,\n                             self.query, self.fragment, parser)\n\n      if rel.userinfo != oth.userinfo ||\n          rel.host.to_s.downcase != oth.host.to_s.downcase ||\n          rel.port != oth.port\n\n        if self.userinfo.nil? && self.host.nil?\n          return self, self.dup\n        end","sourceCodeStart":1207,"sourceCodeEnd":1243,"githubUrl":"https://github.com/ruby/ruby/blob/0e5b888e1c355f3f728f2659f085820937dada48/lib/uri/generic.rb#L1207-L1243","documentation":"Same route_from0 code path as its sibling guard, but here the argument (the starting/base URI) is relative. URI::Generic#route_from requires the base to be absolute so scheme, authority and hierarchy can be compared with the destination.","triggerScenarios":"URI('http://example.com/a/b').route_from(URI.parse('c/d')); absolute.route_from('/other/path') with a path-only base; 'x'.route_to(dest) — route_to calls dest.route_from(self) and self is the relative one.","commonSituations":"Passing request.path as the base when computing relative links; config-supplied base stored as a bare path; accidentally swapping argument order between route_from and route_to.","solutions":["Absolutize the base: URI.join(origin, base_path) before calling route_from","Double-check argument order: a.route_from(b) means 'route from b to a'","Guard both operands with #absolute? before computing a route"],"exampleFix":"# before\ndest = URI('http://example.com/docs/a')\nrel  = dest.route_from('/docs/index.html')\n# BadURIError: relative URI: /docs/index.html\n\n# after\norigin = URI('http://example.com/')\nrel = dest.route_from(origin + 'docs/index.html')   # => \"a\"","handlingStrategy":"validation","validationCode":"def route(dest, base, origin)\n  o    = URI(origin)\n  dest = URI.join(o, dest.to_s)\n  base = URI.join(o, base.to_s)\n  dest.route_from(base)\nend","typeGuard":"def absolute?(u)\n  URI.parse(u.to_s).absolute?\nrescue URI::InvalidURIError\n  false\nend","tryCatchPattern":"dest.route_from(base)\nrescue URI::BadURIError => e\n  raise ArgumentError, \"route_from needs absolute base (#{base}) and dest (#{dest}): #{e.message}\"\nend","preventionTips":["Remember a.route_from(b) means 'route from b to a' — verify argument order","Absolutize both operands with URI.join onto a known origin","Guard both with #absolute? in a single helper used by all link code"],"tags":["ruby","uri","route-from","relative-uri","argument-order"],"backgroundTag":"relative-uri-resolution","analyzedSha":"0e5b888e1c355f3f728f2659f085820937dada48","analyzedAt":"2026-08-21T14:25:43.473Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}