tinyhumansai/openhuman · error

[transport:local] HTTP

Error message

[transport:local] HTTP ${response.status}: ${text || response.statusText}

What it means

LocalTransport surfaces any non-2xx HTTP status from the local core's /rpc endpoint with this message, appending the response body text when present. The status code carries the real diagnosis: 401 means the Bearer token was missing/wrong, 404 means the URL/port is wrong, 5xx means the core itself failed while handling the call.

Solutions

  1. Re-resolve URL and token per call window via the core_rpc_url / core_rpc_token Tauri commands instead of caching them
  2. For 401 against a standalone core, read the current token from {workspace}/core.token or set OPENHUMAN_CORE_TOKEN
  3. For 404/connrefused-style bodies, restart the core process (restart_core_process) so a fresh listener binds
  4. Read the appended body text — the core's error payload names the failing handler

Example fix

// before
const token = cachedToken; // fetched once at boot
// after
const token = await invoke<string>('core_rpc_token'); // per-launch, re-fetch after core restarts
Defensive patterns

Strategy: try-catch

Validate before calling

// Refresh per-launch credentials before long batches:
const rpcUrl = await invoke<string>('core_rpc_url');
const token = await invoke<string>('core_rpc_token');
if (!rpcUrl || !token) throw new Error('core not ready');

Try / catch

try {
  await local.call(method, params);
} catch (err) {
  const m = err instanceof Error ? err.message : '';
  if (m.includes('HTTP 401')) { /* re-fetch token, retry once */ }
  else if (m.includes('HTTP 404')) { /* re-fetch rpcUrl (port rotated), retry once */ }
  else throw err; // 5xx: surface core error text that follows 'HTTP 500'
}

Prevention

When it happens

Trigger: 401 when the cached per-launch hex bearer token is stale (it rotates every core launch and is delivered in-memory via the core_rpc_token Tauri command); 404 when getCoreRpcUrl() resolved to a dead port; 500 when the Rust handler panicked; 502/503 when something proxies the loopback URL.

Common situations: Core restarted between token fetch and call; OPENHUMAN_CORE_REUSE_EXISTING=1 attaching to a core launched with a different token; standalone debugging with ./target/debug/openhuman-core serve while the app still holds the previous session's token (read {workspace}/core.token for that mode).

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/267368510e7a34c0. Report an issue: GitHub.

Appendix: source

Thrown at app/src/services/transport/LocalTransport.ts:77

    try {
      response = await fetch(rpcUrl, {
        method: 'POST',
        headers,
        body: JSON.stringify(payload),
        signal: controller.signal,
      });
    } catch (err) {
      if (controller.signal.aborted) {
        throw new Error(`[transport:local] ${method} timed out after ${this.timeoutMs}ms`);
      }
      throw err;
    } finally {
      clearTimeout(timeoutId);
    }

    if (!response.ok) {
      const text = await response.text();
      throw new Error(`[transport:local] HTTP ${response.status}: ${text || response.statusText}`);
    }

    const json = (await response.json()) as JsonRpcResponse<T>;

    if (json.error) {
      logErr('[transport:local] ← %s error: %s', method, json.error.message);
      throw new Error(json.error.message ?? 'Core RPC returned an error');
    }
    if (!Object.prototype.hasOwnProperty.call(json, 'result')) {
      throw new Error('[transport:local] response missing result');
    }

    log('[transport:local] ← %s id=%d ok', method, id);
    return json.result as T;
  }

  async *stream<T>(
    method: string,

View on GitHub (pinned to 7491200858)