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
- 401 → pass the current token: `--token $(cat <workspace>/core.token)` or refresh OPENHUMAN_CORE_TOKEN; or use --spawn-core
- 404 → include the /rpc path: http://127.0.0.1:7788/rpc
- Verify with curl including the Authorization header to see the raw status
- 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
- Re-read core.token whenever the core restarts — the bearer is per-launch
- Always include the /rpc suffix in the URL
- Prefer --spawn-core for ephemeral audits to eliminate stale-bearer failure modes
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
- RPC ${method} HTTP ${res.status}
- Core RPC HTTP ${response.status}: ${text || response.statusT
- RPC ${method} HTTP ${res.status}
- Invalid ${paramName}: '${value}'. Must be a valid integer ID
- Invalid ${paramName}: ${String(value)}. Type must be an inte
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/ed171742b96d9f29.
Report an issue: GitHub.