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

  1. 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
  2. 404 → fix the URL to include /rpc and the correct port (default http://127.0.0.1:7788/rpc)
  3. 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":{}}'`
  4. 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

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


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