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")
    end

View on GitHub (pinned to ffec79ac33)

Solutions

  1. Prefix the path with '/': call client.get('/api/health'), not client.get('api/health').
  2. If the path is dynamic, normalize it: client.get('/' + path.sub(%r{^/}, '')) to guarantee exactly one leading slash.
  3. For absolute URLs, extract the path with URI.parse(url).request_uri before passing it.
  4. 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

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


AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12). Data as JSON: /api/errors/b5842806bb777711. Report an issue: GitHub.