{"record":{"id":"f13b9720a521f540","repo":"tinyhumansai/openhuman","slug":"unknown-core-rpc-error","errorCode":null,"errorMessage":"Unknown core RPC error","messagePattern":"Unknown core RPC error","errorType":"exception","errorClass":"CoreRpcError","httpStatus":null,"severity":"error","filePath":"app/src/services/coreRpcClient.ts","lineNumber":772,"sourceCode":"        error: json.error,\n      });\n      const rawMessage = json.error.message || 'Core RPC returned an error';\n      const kind = classifyRpcError(rawMessage, undefined, json.error.data);\n      if (kind === 'auth_expired' && !suppressAuthExpiredEvent)\n        dispatchAuthExpired(payload.method, classifyAuthExpiredReason(rawMessage, undefined));\n      throw new CoreRpcError(rawMessage, kind, undefined, json.error.data);\n    }\n    if (!Object.prototype.hasOwnProperty.call(json, 'result')) {\n      throw new Error('Core RPC response missing result');\n    }\n\n    coreRpcLog('HTTP response', { id: payload.id, method: payload.method });\n    return json.result as T;\n  } catch (err) {\n    coreRpcError('Core RPC call failed', sanitizeError(err));\n    if (err instanceof CoreRpcError) throw err;\n    const message = coreRpcErrorMessage(err);\n    throw new CoreRpcError(message, classifyRpcError(message));\n  }\n}\n","sourceCodeStart":754,"sourceCodeEnd":775,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src/services/coreRpcClient.ts#L754-L775","documentation":"Catch-all message produced by `coreRpcErrorMessage(err)` at the bottom of the call wrapper: it is returned only when the caught value is not an `Error` with a message, not a string, and not an object with a usable `message`/`error` string property. So this error means something inside the RPC pipeline threw a non-error value (`undefined`, `null`, a number, a plain `{}`), not that the core reported anything. The rethrown value is a `CoreRpcError` whose kind comes from `classifyRpcError('Unknown core RPC error')` (i.e. 'unknown').","triggerScenarios":"A promise in the pipeline rejects with `undefined` (e.g. an aborted deferred, a `.then()` chain that implicitly returns undefined on a rejection path), or code throws a plain object — note the codebase itself has one: `joinMeetingViaMascotBot` in meetCallService.ts throws `{ message, isCapacityGated }`, which `coreRpcErrorMessage` can rescue only if `message` is non-empty; `{}` or `throw undefined` hits the fallback.","commonSituations":"Third-party or sibling code doing `throw {}` / `Promise.reject()` without a reason; an abort/cancel path that rejects with a non-Error; a fetch polyfill rejecting with an event object instead of a TypeError.","solutions":["Look at the preceding `core-rpc:error` 'Core RPC call failed' log line — it prints `sanitizeError(err)`, the raw caught value, which identifies the throw site","Grep the codebase for `throw {` and bare `Promise.reject(` and convert them to `throw new Error(...)`","Reproduce with the debugger paused on the catch to see the actual value of `err`","If the non-Error comes from a dependency, wrap that call in try/catch and rethrow a real Error"],"exampleFix":"// before (meetCallService.ts pattern)\nthrow { message: 'Please paste a meeting link.', isCapacityGated: false };\n\n// after\nclass CapacityGateError extends Error {\n  constructor(msg, readonly isCapacityGated: boolean) { super(msg); }\n}\nthrow new CapacityGateError('Please paste a meeting link.', false);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function hasMessage(e: unknown): e is { message: string } {\n  return !!e && typeof e === 'object' && typeof (e as any).message === 'string' && (e as any).message.length > 0;\n}","tryCatchPattern":"try { await coreRpcClient.call(m, p); }\ncatch (e) {\n  const msg = e instanceof Error ? e.message\n    : typeof e === 'string' ? e\n    : hasMessage(e) ? e.message : 'call failed (non-error thrown)';\n  // always log the raw value too — it identifies a `throw {}` site\n  console.warn('raw rejection:', e);\n  throw new Error(msg);\n}","preventionTips":["Never `throw {}` — always throw new Error or a subclass (grep the repo for `throw {` and fix)","Never Promise.reject() without a reason value","Log the raw caught value alongside the normalized message so 'Unknown core RPC error' is immediately diagnosable"],"tags":["error-handling","core-rpc","javascript"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}