ruvnet/RuView · warning · Error

Unsupported host: ${name}

Error message

Unsupported host: ${name}

What it means

RateLimitMiddleware.dispatch (rate_limit.py:335) raises HTTPException 429 'Rate limit exceeded' when the per-client sliding-window counter denies the request. The response carries X-RateLimit-Limit/Remaining/Reset headers plus a computed Retry-After (seconds until window reset). Limiting keys derive from the client identity (IP or authenticated user), with a default_limit and a higher authenticated_limit.

Source

Thrown at harness/homecore/src/hosts/index.js:15

// SPDX-License-Identifier: MIT

import claudeCode from './claude-code.js';
import codex from './codex.js';

export { claudeCode, codex };

export const HOSTS = Object.freeze({
  'claude-code': claudeCode,
  codex,
});

export function getHost(name) {
  const host = HOSTS[name];
  if (!host) throw new Error(`Unsupported host: ${name}`);
  return host;
}

View on GitHub (pinned to 4685618388)

Solutions

  1. Honor the Retry-After header: sleep that many seconds, then resume with exponential backoff
  2. Authenticate requests so the higher authenticated_limit applies instead of the anonymous per-IP limit
  3. Reduce request rate (client-side throttle/caching) or batch endpoints
  4. Server-side: raise default_limit/authenticated_limit in Settings or set enable_rate_limiting=False for local development; add hot paths to the skip list

Example fix

# before
for i in range(1000):
    requests.get(url, headers=headers)  # triggers 429
# after
resp = requests.get(url, headers=headers)
if resp.status_code == 429:
    time.sleep(int(resp.headers["Retry-After"]) + 1)
    resp = requests.get(url, headers=headers)
Defensive patterns

Strategy: retry

Validate before calling

def should_throttle(response) -> bool:
    """Detect the 429 this middleware raises before planning the next call."""
    return response.status_code == 429 or "X-RateLimit-Remaining" in response.headers and response.headers["X-RateLimit-Remaining"] == "0"

Try / catch

import time
from fastapi import HTTPException

try:
    response = client.get("/api/data", headers=headers)
except HTTPException as e:
    if getattr(e, "status_code", None) == 429:
        wait = int(e.headers["Retry-After"]) + 1 if e.headers else 1
        time.sleep(wait)
        response = client.get("/api/data", headers=headers)  # single retry after backoff
    else:
        raise

Prevention

When it happens

Trigger: Bursting more than default_limit requests from one IP within window_size seconds while unauthenticated; a poll loop or k6/locust load test hammering /api/* endpoints; many users behind one NAT/IP sharing a single unauthenticated bucket; retries without backoff after 429s.

Common situations: Load tests against a default-configured server; aggressive frontend polling; CI suites running parallel requests from one runner IP; health checks counted against the same bucket when the path is not in the skip list.

Related errors


AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16). Data as JSON: /api/errors/82c14f44c1cb88be. Report an issue: GitHub.