koala73/worldmonitor · warning · ArgumentError
get() needs a host-relative API path starting with '/'
Error message
get() needs a host-relative API path starting with '/'
What it means
Raised as ArgumentError by Client#get (line 118) when the path argument does not start with '/'. This is a synchronous pre-flight validation — no network call is made. The guard exists because get() concatenates base_url + path directly (line 120), so a non-slash path would either silently join incorrectly or hit the wrong endpoint. It forces callers to pass host-relative paths (e.g. '/api/health'), not bare names or absolute URLs.
Source
Thrown at sdk/ruby/lib/worldmonitor.rb:118
# List every MCP tool (public - no key needed).
def list_tools
rpc("tools/list")
end
# List MCP prompt templates (public).
def list_prompts
rpc("prompts/list")
end
# List MCP resources (public).
def list_resources
rpc("resources/list")
end
# GET a raw REST path (host-relative, e.g. "/api/health").
def get(path, params = {})
raise ArgumentError, "get() needs a host-relative API path starting with '/'" unless path.start_with?("/")
url = base_url + path
query = stringify_keys(params)
url += "?#{URI.encode_www_form(query.map { |k, v| [k, stringify_value(v)] })}" unless query.empty?
status, content_type, body = @transport.call(
{ url: url, method: "GET", headers: headers(accept: "application/json") },
timeout
)
value = self.class.parse_body(body, content_type)
raise APIError.new(status, value) unless (200..299).cover?(status)
value
end
# API status / health check.
def health
get("/api/health")
endView on GitHub (pinned to ffec79ac33)
Solutions
- Prefix the path with '/': call client.get('/api/health'), not client.get('api/health').
- If the path is dynamic, normalize it: client.get('/' + path.sub(%r{^/}, '')) to guarantee exactly one leading slash.
- For absolute URLs, extract the path with URI.parse(url).request_uri before passing it.
- Prefer the curated helpers (client.health, etc.) which already use correct host-relative paths.
Example fix
# before
client.get('api/health')
# after
path = 'api/health'
client.get('/' + path.sub(%r{\A/+}, '')) Defensive patterns
Strategy: validation
Validate before calling
# Normalize the path before calling get so a missing slash never reaches the SDK.
def safe_get(client, path, **params)
raise ArgumentError, 'path is required' if path.nil? || path.empty?
path = '/' + path.sub(%r{\A/+}, '')
client.get(path, **params)
end Type guard
def host_relative_path?(path)
path.is_a?(String) && path.start_with?('/') && !path.start_with?('//')
end Try / catch
begin
client.get(path)
rescue ArgumentError => e
if e.message.start_with?("get() needs a host-relative")
path = '/' + path.to_s.sub(%r{\A/+}, '')
retry
end
raise
end Prevention
- Always pass a literal leading slash: '/api/health', never 'api/health'.
- For dynamic paths, normalize with '/' + path.sub(%r{\A/+}, '') at the call site.
- For absolute URLs, extract the path via URI.parse(url).request_uri first.
- Prefer curated helpers (client.health) over raw get() so the path is always correct.
When it happens
Trigger: Calling client.get('api/health') (missing leading slash), client.get('https://api.worldmonitor.app/api/health') (absolute URL instead of host-relative), client.get('') (empty string), or a dynamically built path like client.get("api/#{endpoint}") that omits the slash. Also triggers when interpolating a config value that does not carry a leading slash.
Common situations: Copy-pasting a path from a browser address bar (which drops the leading slash). Building a path from a variable that was stripped. Passing a full URL out of habit. Treating get() like Faraday/HTTParty which accept absolute URLs.
Related errors
- get() needs a host-relative API path starting with '/'
- HTTP #{status}: #{body}
- MCP error #{code}: #{message}
- Webhook URL is not a valid URL
- Webhook URL must use HTTPS
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/b5842806bb777711.
Report an issue: GitHub.