{"record":{"id":"125cfe93b2bc6e31","repo":"tinyhumansai/openhuman","slug":"restart-core-is-only-available-in-the-desktop-app","errorCode":null,"errorMessage":"Restart Core is only available in the desktop app.","messagePattern":"Restart Core is only available in the desktop app\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"app/src/services/coreProcessControl.ts","lineNumber":18,"sourceCode":"/**\n * Thin wrapper around the Tauri `restart_core_process` IPC command.\n *\n * Surfaced via the Home blocking screen's \"Restart Core\" button (#1527) so\n * the user has a one-click recovery when the local sidecar has crashed or\n * is stuck. Outside Tauri (web preview / Vitest harness) this is a no-op\n * that returns a friendly error string.\n */\n// `safeInvoke` (in place of `@tauri-apps/api/core::invoke`) converts the CEF\n// `window.ipc.postMessage` synchronous throw — Sentry TAURI-REACT-7 /\n// TAURI-REACT-6 — into a rejected Promise so the caller's `await` /\n// `.catch(...)` can handle it instead of bubbling as an unhandled rejection.\nimport { safeInvoke as invoke, isTauri } from '../utils/tauriCommands/common';\nimport { clearCoreRpcTokenCache } from './coreRpcClient';\n\nexport async function restartCoreProcess(): Promise<void> {\n  if (!isTauri()) {\n    throw new Error('Restart Core is only available in the desktop app.');\n  }\n  await invoke('restart_core_process');\n  // The Tauri shell mints a fresh `OPENHUMAN_CORE_TOKEN` for the new core\n  // process. Drop the cached bearer so token-bearing long-lived consumers\n  // (e.g. webhook SSE, see #1922) reconnect with the new value.\n  clearCoreRpcTokenCache();\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src/services/coreProcessControl.ts#L1-L26","documentation":"A deliberate environment guard in restartCoreProcess(): restarting the embedded core is only possible inside the Tauri desktop shell, because only the shell owns the core child process (core_process.rs). When isTauri() is false — plain browser preview (pnpm dev) or the Vitest harness — the function throws this friendly error instead of attempting an invoke that cannot work.","triggerScenarios":"Calling restartCoreProcess() from the web preview opened via the Vite dev server, in unit tests, or in any non-Tauri embedding. The Tauri IPC command restart_core_process simply does not exist outside the shell.","commonSituations":"Developers exercising Settings/IPC flows in a browser; tests importing a component that mounts a Restart Core control; a menu item not hidden when running outside Tauri.","solutions":["Guard the call site: only show/enable the Restart Core control when isTauri() is true","For browser-based development, restart the dev core process externally instead (or relaunch pnpm dev:app)","In tests, either assert the error message or mock the module"],"exampleFix":"// before\n<Button onClick={() => restartCoreProcess()}>Restart Core</Button>\n\n// after\n{isTauri() && (\n  <Button onClick={() => restartCoreProcess().catch(showError)}>Restart Core</Button>\n)}","handlingStrategy":"validation","validationCode":"import { isTauri } from '../utils/tauriCommands/common';\nif (!isTauri()) {\n  hideRestartCoreControl(); // browser preview / tests — the call cannot succeed\n}","typeGuard":null,"tryCatchPattern":"try {\n  await restartCoreProcess();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('desktop app')) {\n    setNotice('Restart Core is unavailable outside the desktop app.');\n  } else throw e;\n}","preventionTips":["Condition every shell-IPC control on isTauri() at render time","Centralize desktop-only actions in one module so guards are not repeated ad hoc","In tests, assert this exact message to pin the environment guard"],"tags":["tauri","environment-guard","desktop","precondition"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}