tinyhumansai/openhuman · error · Error

Not running in Tauri

Error message

Not running in Tauri

What it means

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.

Source

Thrown at app/src/utils/tauriCommands/service.ts:35

export interface AgentServerStatus {
  running: boolean;
  url: string;
}

export interface DaemonHostConfig {
  show_tray: boolean;
}

export interface RestartStatus {
  accepted: boolean;
  source: string;
  reason: string;
}

export async function openhumanServiceInstall(): Promise<CommandResponse<ServiceStatus>> {
  if (!isTauri()) {
    throw new Error('Not running in Tauri');
  }
  try {
    return await callCoreRpc<CommandResponse<ServiceStatus>>({
      method: 'openhuman.service_install',
    });
  } catch {
    const raw = await invoke<string>('service_install_direct');
    return parseServiceCliOutput<ServiceStatus>(raw);
  }
}

export async function openhumanServiceStart(): Promise<CommandResponse<ServiceStatus>> {
  if (!isTauri()) {
    throw new Error('Not running in Tauri');
  }
  try {
    return await callCoreRpc<CommandResponse<ServiceStatus>>({ method: 'openhuman.service_start' });
  } catch {

View on GitHub (pinned to 7491200858)

Solutions

  1. Run service management inside the desktop shell (`pnpm dev:app` or the packaged app).
  2. Render the install/start/stop controls as disabled when `!isTauri()`, since the whole service block is desktop-only.
  3. Mock `isTauri` true and stub `callCoreRpc`/`invoke` in unit tests for these actions.
  4. Catch the throw and show 'service controls require the desktop app'.
  5. 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.

Example fix

// before
<button onClick={() => openhumanServiceInstall()}>Install</button>

// after
<button disabled={!isTauri()} onClick={() => openhumanServiceInstall()}>
  Install
</button>
Defensive patterns

Strategy: validation

Validate before calling

import { isTauri } from '../utils/tauriCommands/common';

if (!isTauri()) {
  // both the core RPC and the service_install_direct fallback are shell IPC
  throw new Error('Service management requires the desktop app');
}
await openhumanServiceInstall();

Type guard

function isNotInTauriError(e: unknown): e is Error {
  return e instanceof Error && e.message === 'Not running in Tauri';
}

Try / catch

try {
  const r = await openhumanServiceInstall();
} catch (e) {
  if (e instanceof Error && e.message === 'Not running in Tauri') {
    showDesktopOnlyNotice();
    return;
  }
  throw e; // core RPC and direct-invoke failures surface here instead
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/5c790ba153a0d494. Report an issue: GitHub.