tinyhumansai/openhuman · error · Error

RPC ${method} returned non-JSON HTTP ${res.status}: ${bodyTe

Error message

RPC ${method} returned non-JSON HTTP ${res.status}: ${bodyText.slice(0, 200)}

What it means

After fetch resolves, rpc() in scripts/debug/agent-prepare-context-audit.mjs reads the body as text and attempts JSON.parse; on failure it throws 'RPC <method> returned non-JSON HTTP <status>' with the first 200 characters of the body. It means the endpoint answered — but with HTML/plain text (proxy error page, auth-portal redirect, directory listing) rather than a JSON-RPC response.

Source

Thrown at scripts/debug/agent-prepare-context-audit.mjs:277

        jsonrpc: "2.0",
        id: `apc-${Date.now()}-${Math.random().toString(16).slice(2)}`,
        method,
        params,
      }),
    });
  } 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}: ${bodyText.slice(0, 200)}`,
    );
  }
  if (!res.ok) throw new Error(`RPC ${method} HTTP ${res.status}`);
  if (body.error)
    throw new Error(
      `RPC ${method} error: ${JSON.stringify(body.error).slice(0, 300)}`,
    );
  return body.result;
}

// ── Transcript reading ──────────────────────────────────────────────────────

async function walkJsonl(dir) {
  const out = [];
  async function walk(current) {
    let entries;
    try {

View on GitHub (pinned to a221052e0d)

Solutions

  1. Use the full endpoint including /rpc: http://127.0.0.1:7788/rpc (the script's default)
  2. Check what actually answers: curl -i the URL and look at Content-Type — JSON-RPC answers application/json
  3. Free or change the port if another service occupies it (the spawned-core path derives the port from --core-url)
  4. Unset OPENHUMAN_CORE_RPC_URL if it carries a stale/wrong endpoint from another tooling

Example fix

# before
$ node scripts/debug/agent-prepare-context-audit.mjs --core-url http://127.0.0.1:7788
Error: RPC core.ping returned non-JSON HTTP 200: <!doctype html>...

# after
$ node scripts/debug/agent-prepare-context-audit.mjs --core-url http://127.0.0.1:7788/rpc
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: the endpoint must speak JSON before any RPC
const res = await fetch(coreUrl, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "core.ping", params: {} }) });
const ct = res.headers.get("content-type") || "";
if (!ct.includes("json")) throw new Error(`${coreUrl} is not a JSON-RPC endpoint (content-type: ${ct || "none"}) — did you mean ${coreUrl.replace(/\/?$/, "")}/rpc ?`);

Try / catch

try {
  return await rpc(coreUrl, token, method, params);
} catch (e) {
  if (/returned non-JSON/.test(e.message)) {
    throw new Error(`Wrong endpoint? ${coreUrl} must end with /rpc and point at openhuman-core. Original: ${e.message}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: --core-url / OPENHUMAN_CORE_RPC_URL pointing at a URL that is not the JSON-RPC endpoint: the bare host root (http://127.0.0.1:7788 without /rpc), a port serving a different service (Vite dev server returning HTML), or a corporate proxy intercepting with an HTML block page. The HTTP status in the message (200, 502, 302-followed-200, ...) hints at which.

Common situations: Forgetting the /rpc suffix when hand-writing --core-url; port 7788 already occupied by another process so the script talks to the wrong server; OPENHUMAN_CORE_RPC_URL inherited from a different tool that expects a base URL rather than the full /rpc path; VPN/proxy rewriting localhost-less URLs.

Related errors


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