tinyhumansai/openhuman · error

Core RPC returned an error

Error message

Core RPC returned an error

What it means

Thrown by parseQueueEnvelope() when the payload is an object carrying an 'error' property whose 'message' is missing — the ?? fallback text 'Core RPC returned an error' is used. This is a core-side failure that arrived wrapped inside a success-shaped response (envelope.error) instead of the JSON-RPC error channel that coreRpcClient would have converted to a CoreRpcError, so the original error detail is lost.

Source

Thrown at app/src/services/api/providerSurfacesApi.ts:18

import type { RespondQueueList } from '../../types/providerSurfaces';
import { callCoreRpc } from '../coreRpcClient';

interface ProviderSurfacesQueueEnvelope {
  data?: RespondQueueList;
  result?: { data?: RespondQueueList };
}

const EMPTY_QUEUE: RespondQueueList = { items: [], count: 0 };

function parseQueueEnvelope(raw: unknown): RespondQueueList {
  if (!raw || typeof raw !== 'object') {
    throw new Error('provider_surfaces_list_queue: unexpected empty response');
  }

  const envelope = raw as ProviderSurfacesQueueEnvelope & { error?: { message?: string } };
  if (envelope.error) {
    throw new Error(envelope.error.message ?? 'Core RPC returned an error');
  }
  const candidate = envelope.result?.data ?? envelope.data;
  if (!candidate || !Array.isArray(candidate.items) || typeof candidate.count !== 'number') {
    return EMPTY_QUEUE;
  }
  return candidate;
}

export const providerSurfacesApi = {
  async listQueue(): Promise<RespondQueueList> {
    const raw = await callCoreRpc<unknown>({ method: 'openhuman.provider_surfaces_list_queue' });
    return parseQueueEnvelope(raw);
  },
};

View on GitHub (pinned to a221052e0d)

Solutions

  1. Log the full envelope.error (code/data fields), not just the message, to recover the real failure
  2. Check the core logs at the request timestamp — the underlying error is usually visible core-side
  3. Restart the core; a wedged respond-queue store often clears on a fresh process
  4. If developing the client, include code/data in the thrown message: envelope.error.message ?? `${envelope.error.code}` ?? fallback

Example fix

// before
throw new Error(envelope.error.message ?? 'Core RPC returned an error');

// after
const e = envelope.error;
throw new Error(e?.message ?? `Core RPC error ${e?.code ?? 'unknown'} ${JSON.stringify(e?.data ?? '')}`.trim());
Defensive patterns

Strategy: try-catch

Type guard

function isCoreErrorEnvelope(v: unknown): v is { error: { message?: string; code?: number; data?: unknown } } {
  return !!v && typeof v === 'object' && 'error' in (v as Record<string, unknown>);
}

Try / catch

try {
  const queue = await providerSurfacesApi.listQueue();
} catch (e) {
  // The thrown message is generic; capture the envelope yourself for diagnostics
  log.error('provider_surfaces_list_queue failed', { error: e });
  if (e instanceof Error && e.message === 'Core RPC returned an error') {
    checkCoreLogsAndRestart(); // message-less error envelope — inspect core side
  } else throw e;
}

Prevention

When it happens

Trigger: The relayed response for provider_surfaces_list_queue is {error: {}} or {error: {code: ...}} with no message — e.g. a Tauri relay_http_rpc wrapping an internal failure, or a core controller embedding a serialized error struct into its result.

Common situations: Core crashed or store locked while answering and the shell relays an error object without a message; older core whose error serialization omitted message; nested/double-wrapped envelopes from transport shims.

Related errors


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