{"record":{"id":"5c790ba153a0d494","repo":"tinyhumansai/openhuman","slug":"not-running-in-tauri-5c790b","errorCode":null,"errorMessage":"Not running in Tauri","messagePattern":"Not running in Tauri","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/src/utils/tauriCommands/service.ts","lineNumber":35,"sourceCode":"\nexport interface AgentServerStatus {\n  running: boolean;\n  url: string;\n}\n\nexport interface DaemonHostConfig {\n  show_tray: boolean;\n}\n\nexport interface RestartStatus {\n  accepted: boolean;\n  source: string;\n  reason: string;\n}\n\nexport async function openhumanServiceInstall(): Promise<CommandResponse<ServiceStatus>> {\n  if (!isTauri()) {\n    throw new Error('Not running in Tauri');\n  }\n  try {\n    return await callCoreRpc<CommandResponse<ServiceStatus>>({\n      method: 'openhuman.service_install',\n    });\n  } catch {\n    const raw = await invoke<string>('service_install_direct');\n    return parseServiceCliOutput<ServiceStatus>(raw);\n  }\n}\n\nexport async function openhumanServiceStart(): Promise<CommandResponse<ServiceStatus>> {\n  if (!isTauri()) {\n    throw new Error('Not running in Tauri');\n  }\n  try {\n    return await callCoreRpc<CommandResponse<ServiceStatus>>({ method: 'openhuman.service_start' });\n  } catch {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/app/src/utils/tauriCommands/service.ts#L17-L53","documentation":"Guard thrown by `openhumanServiceInstall` before either of its two paths can run: the primary `openhuman.service_install` core RPC, or its catch-fallback `invoke('service_install_direct')` which parses CLI output via `parseServiceCliOutput`. Both ride Tauri IPC (the local RPC goes through the `relay_http_rpc` shell command), so when `isTauri()` is false the wrapper throws once, up front, instead of failing twice downstream. It means the renderer has no desktop-shell bridge at all.","triggerScenarios":"Clicking 'Install service' on the service/daemon settings screen while the frontend runs in a plain browser; calling `openhumanServiceInstall()` in jsdom tests without mocking `isTauri`; triggering it during the CEF bootstrap gap before `__TAURI_INTERNALS__.invoke` exists.","commonSituations":"Developing the service-management settings pane with `pnpm dev` (Vite-only) instead of `pnpm dev:app`; tests exercising install flows; a web-hosted preview where the settings screen is still navigable.","solutions":["Run service management inside the desktop shell (`pnpm dev:app` or the packaged app).","Render the install/start/stop controls as disabled when `!isTauri()`, since the whole service block is desktop-only.","Mock `isTauri` true and stub `callCoreRpc`/`invoke` in unit tests for these actions.","Catch the throw and show 'service controls require the desktop app'.","If a remote-core mode should manage its service, note the fallback path (`service_install_direct`) is shell-local and cannot work remotely — keep the gate for this function."],"exampleFix":"// before\n<button onClick={() => openhumanServiceInstall()}>Install</button>\n\n// after\n<button disabled={!isTauri()} onClick={() => openhumanServiceInstall()}>\n  Install\n</button>","handlingStrategy":"validation","validationCode":"import { isTauri } from '../utils/tauriCommands/common';\n\nif (!isTauri()) {\n  // both the core RPC and the service_install_direct fallback are shell IPC\n  throw new Error('Service management requires the desktop app');\n}\nawait openhumanServiceInstall();","typeGuard":"function isNotInTauriError(e: unknown): e is Error {\n  return e instanceof Error && e.message === 'Not running in Tauri';\n}","tryCatchPattern":"try {\n  const r = await openhumanServiceInstall();\n} catch (e) {\n  if (e instanceof Error && e.message === 'Not running in Tauri') {\n    showDesktopOnlyNotice();\n    return;\n  }\n  throw e; // core RPC and direct-invoke failures surface here instead\n}","preventionTips":["Disable the whole service-management block when !isTauri().","Remember the catch-fallback invoke('service_install_direct') is also Tauri-bound — the guard protects both paths.","Mock isTauri and both transports in tests.","Prefer gating at render time over catching at click time for destructive service actions."],"tags":["tauri","environment-guard","frontend","service-management","daemon","ipc"],"backgroundTag":"not-running-in-tauri","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}