ruby/ruby · error · BadURIError
relative URI: #{oth}
Error message
relative URI: #{oth} What it means
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.
Source
Thrown at lib/uri/generic.rb:1225
else
return tmp
end
end
return '../' * src_path.size + tmp
end
private :route_from_path
# :startdoc:
# :stopdoc:
def route_from0(oth)
oth = parser.__send__(:convert_to_uri, oth)
if self.relative?
raise BadURIError,
"relative URI: #{self}"
end
if oth.relative?
raise BadURIError,
"relative URI: #{oth}"
end
if self.scheme != oth.scheme
return self, self.dup
end
rel = URI::Generic.new(nil, # it is relative URI
self.userinfo, self.host, self.port,
nil, self.path, self.opaque,
self.query, self.fragment, parser)
if rel.userinfo != oth.userinfo ||
rel.host.to_s.downcase != oth.host.to_s.downcase ||
rel.port != oth.port
if self.userinfo.nil? && self.host.nil?
return self, self.dup
endView on GitHub (pinned to 0e5b888e1c)
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
Example fix
# before
dest = URI('http://example.com/docs/a')
rel = dest.route_from('/docs/index.html')
# BadURIError: relative URI: /docs/index.html
# after
origin = URI('http://example.com/')
rel = dest.route_from(origin + 'docs/index.html') # => "a" Defensive patterns
Strategy: validation
Validate before calling
def route(dest, base, origin) o = URI(origin) dest = URI.join(o, dest.to_s) base = URI.join(o, base.to_s) dest.route_from(base) end
Type guard
def absolute?(u) URI.parse(u.to_s).absolute? rescue URI::InvalidURIError false end
Try / catch
dest.route_from(base)
rescue URI::BadURIError => e
raise ArgumentError, "route_from needs absolute base (#{base}) and dest (#{dest}): #{e.message}"
end Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- relative URI: #{self}
- both URI are relative
- not an HTTP URI
- no host component for URI
- no HTTP request path given
AI-assisted analysis of ruby/ruby@0e5b888e1c (2026-08-21).
Data as JSON: /api/errors/4a2241d86a6496f5.
Report an issue: GitHub.