tinyhumansai/openhuman · error · Error

Core RPC returned an error

Error message

Core RPC returned an error

What it means

The core answered HTTP 200 with a JSON-RPC envelope whose `error` member is truthy — the RPC method failed core-side. This generic text appears only when json.error.message is null/undefined, itself a JSON-RPC 2.0 protocol violation, so it usually means the core (or something in front of it) produced a non-conformant error object with no message.

Source

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

    } 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,
    params: unknown,
    opts?: { signal?: AbortSignal }
  ): AsyncIterable<T> {
    // Local HTTP doesn't support streaming natively in this project.
    // Fall back to a single call and yield the result.
    const result = await this.call<T>(method, params, opts);
    yield result;

View on GitHub (pinned to a221052e0d)

Solutions

  1. Log json.error.code — the numeric code often identifies the failure even without a message
  2. Reproduce the call against a real core (./target/debug/openhuman-core serve) and check the core log for the handler error
  3. If you control the server side, always serialize {code, message} per JSON-RPC 2.0
  4. If using the mock server, fix its error fixture to include a message

Example fix

// before (mock/server error without message)
res.json({ error: { code: -32603 } });

// after
res.json({ error: { code: -32603, message: 'agent session not found' } });
Defensive patterns

Strategy: try-catch

Try / catch

Catch and treat err.message as unreliable for this case — show a generic failure notice, log the method name and request id, and correlate with the core-side log where the real error text lives.

Prevention

When it happens

Trigger: Calling any openhuman.* method whose handler returns Err where the error serializes without a message field — e.g. {error:{code:-32603}}; a mock/dev server (scripts/mock-api-core.mjs) with message-less error fixtures; a gateway re-serializing JSON-RPC errors.

Common situations: Mock backend returning error objects lacking message; a domain handler building RpcError from a code map without a message; version skew between the frontend's method expectations and the core handler's error shape.

Related errors


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