tinyhumansai/openhuman · error · Error

RPC ${method} HTTP ${res.status}

Error message

RPC ${method} HTTP ${res.status}

What it means

When the response body parses as JSON but res.ok is false, harness-cache-audit's rpc() throws this transport-level status error (the JSON-RPC-level error case is separate and even less informative). Reaching this branch means an HTTP server answered with JSON and a non-2xx status — in practice almost always 401 authentication on the core's /rpc endpoint, or 404 from a wrong path.

Source

Thrown at scripts/debug/harness-cache-audit.mjs:230

      }),
    });
  } catch (err) {
    if (err?.name === "AbortError") {
      throw new Error(`RPC ${method} timed out after ${timeoutMs}ms`);
    }
    throw err;
  } finally {
    clearTimeout(timeout);
  }
  const bodyText = await res.text();
  let body;
  try {
    body = JSON.parse(bodyText);
  } catch {
    throw new Error(`RPC ${method} returned non-JSON HTTP ${res.status}`);
  }
  if (!res.ok) {
    throw new Error(`RPC ${method} HTTP ${res.status}`);
  }
  if (body.error) {
    throw new Error(`RPC ${method} error`);
  }
  return body.result;
}

async function walkJsonl(dir) {
  const out = [];
  async function walk(current) {
    let entries;
    try {
      entries = await readdir(current, { withFileTypes: true });
    } catch {
      return;
    }
    await Promise.all(
      entries.map(async (entry) => {

View on GitHub (pinned to a221052e0d)

Solutions

  1. 401 → pass the current token: `--token $(cat <workspace>/core.token)` or refresh OPENHUMAN_CORE_TOKEN; or use --spawn-core
  2. 404 → include the /rpc path: http://127.0.0.1:7788/rpc
  3. Verify with curl including the Authorization header to see the raw status
  4. Check for proxy layers (corporate proxy, service mesh) adding their own status codes

Example fix

# before
node scripts/debug/harness-cache-audit.mjs --token stale-token-from-yesterday
# Error: RPC openhuman.agent_chat HTTP 401

# after
node scripts/debug/harness-cache-audit.mjs --token $(cat ~/.openhuman/users/<id>/workspace/core.token)
Defensive patterns

Strategy: validation

Validate before calling

const probe = await fetch(coreUrl, {
  method: "POST",
  headers: { "content-type": "application/json", authorization: `Bearer ${token}` },
  body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "core.ping", params: {} }),
});
if (probe.status === 401 || probe.status === 404) {
  console.error(`endpoint check failed with ${probe.status} — ${probe.status === 401 ? "refresh the bearer" : "fix the URL (include /rpc)"}`);
  process.exit(2);
}

Type guard

const isHttpStatusError = (err) => /HTTP [45]\d{2}$/.test(err?.message || "");

Try / catch

try {
  return await rpc(coreUrl, token, method, params);
} catch (err) {
  if (/HTTP 401$/.test(err.message)) {
    token = (await readFile(path.join(workspace, "core.token"), "utf8")).trim(); // re-read after core restart
    return await rpc(coreUrl, token, method, params);
  }
  throw err;
}

Prevention

When it happens

Trigger: 401 from a stale/wrong bearer (core restarted, per-launch token rotated, staging token used against prod workspace); 404 from --core-url missing the /rpc suffix; 403 from a reverse proxy; 502/503 while the core restarts under load.

Common situations: core.token read from a workspace whose core has since relaunched with a new token; mixed OPENHUMAN_CORE_TOKEN in the environment overriding the file-based one invisibly; URL pasted from the health endpoint docs rather than the RPC one.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/ed171742b96d9f29. Report an issue: GitHub.