tinyhumansai/openhuman · error · Error
RPC ${method} HTTP ${res.status}
Error message
RPC ${method} HTTP ${res.status} What it means
If the response parses as JSON but res.ok is false, rpc() throws this bare HTTP-status error. At this layer the request reached an HTTP server that speaks JSON but rejected the request at the transport level — as opposed to error 226, which is a JSON-RPC-level failure inside a 200 response. The two most common causes are 401 (bad/missing bearer) and 404 (wrong path).
Source
Thrown at scripts/debug/goals-live.mjs:208
method,
params,
}),
});
} catch (err) {
if (err?.name === "AbortError")
throw new Error(`RPC ${method} timed out after ${timeoutMs}ms`);
throw err;
} finally {
clearTimeout(timer);
}
const text = await res.text();
let body;
try {
body = JSON.parse(text);
} catch {
throw new Error(`RPC ${method} returned non-JSON HTTP ${res.status}: ${text.slice(0, 200)}`);
}
if (!res.ok) throw new Error(`RPC ${method} HTTP ${res.status}`);
if (body.error)
throw new Error(`RPC ${method} error: ${body.error.message || JSON.stringify(body.error)}`);
return body.result;
}
// RpcOutcome serializes either as the bare value (no logs) or { result, logs }.
function unwrap(result) {
if (result && typeof result === "object" && "result" in result && "logs" in result) {
return { value: result.result, logs: result.logs || [] };
}
return { value: result, logs: [] };
}
function renderGoals(doc) {
const items = doc?.items || [];
if (items.length === 0) return " (no goals)";
return items.map((g) => ` - [${g.id}] ${g.text}`).join("\n");
}View on GitHub (pinned to a221052e0d)
Solutions
- 401 → refresh the bearer: re-read the current <workspace>/core.token, pass --token explicitly, or run --spawn-core so the script owns a fresh token
- 404 → fix the URL to include /rpc and the correct port (default http://127.0.0.1:7788/rpc)
- Confirm the endpoint contract with curl: `curl -s -o /dev/null -w '%{http_code}' -X POST <url> -H 'authorization: Bearer <tok>' -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"core.ping","params":{}}'`
- If 5xx, check the core's own logs — it is receiving but failing the request
Example fix
# before: token from an older core launch node scripts/debug/goals-live.mjs --token $(cat /old/workspace/core.token) # Error: RPC openhuman.memory_goals_list HTTP 401 # after: re-read the live workspace's token node scripts/debug/goals-live.mjs --token $(cat ~/.openhuman/users/<id>/workspace/core.token)
Defensive patterns
Strategy: validation
Validate before calling
// cheap authenticated ping before the audit: surfaces 401/404 immediately
const res = 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 (res.status === 401) { console.error("stale or wrong bearer — refresh core.token"); process.exit(2); }
if (res.status === 404) { console.error("URL missing /rpc or wrong port"); process.exit(2); } Type guard
const isHttpLevelError = (err) => /HTTP \d{3}$/.test(err?.message || ""); Try / catch
try {
return await rpc(coreUrl, token, method, params);
} catch (err) {
if (/HTTP 401$/.test(err.message)) { token = await refreshToken(); return await rpc(coreUrl, token, method, params); }
throw err;
} Prevention
- Treat 401 as a token-refresh signal: re-read <workspace>/core.token after any core restart
- Scope env vars per invocation (env -u OPENHUMAN_CORE_TOKEN ...) to avoid invisible overrides
- Prefer --spawn-core in throwaway runs; it removes token staleness entirely
When it happens
Trigger: 401: the bearer is wrong — token from a previous core launch (per-launch hex rotates), token truncated by shell quoting, or readToken picked a stale core.token; 404: --core-url missing the /rpc suffix or pointing at the wrong port; 405: GET sent where only POST is accepted (malformed invocation); 503: core shutting down.
Common situations: Core restarted between the time core.token was read and the RPC fired; mixing tokens across staging/prof production workspaces; URL copy-pasted from docs without the /rpc path; reverse proxy in front of the core requiring additional auth.
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/4f2556fc67401387.
Report an issue: GitHub.