tinyhumansai/openhuman · error · Error

Not running in Tauri

Error message

Not running in Tauri

What it means

memoryListDocuments wraps openhuman.memory_list_documents and unwraps the { data: { documents } } RpcOutcome envelope, but before any of that it runs the isTauri() guard that throws 'Not running in Tauri'. The shared isTauri() (common.ts:30) is stricter than the official flag: window must exist and window.__TAURI_INTERNALS__.invoke must be a function, so it is false in browsers, jsdom tests, and the CEF bootstrap gap (#1472).

Source

Thrown at app/src/utils/tauriCommands/memory.ts:104

    isTauri()
  );
  if (!isTauri()) {
    console.debug('[memory] syncMemoryClientToken: exit — skipped (not Tauri)');
    return;
  }
  try {
    console.debug('[memory] syncMemoryClientToken: payload → memory.init (local-only)');
    // jwt_token is passed for backward compatibility but ignored by the core.
    await callCoreRpc<boolean>({ method: 'openhuman.memory_init', params: { jwt_token: token } });
    console.info('[memory] syncMemoryClientToken: exit — ok');
  } catch (err) {
    console.warn('[memory] syncMemoryClientToken: exit — error:', err);
  }
}

export async function memoryListDocuments(namespace?: string): Promise<unknown> {
  if (!isTauri()) {
    throw new Error('Not running in Tauri');
  }
  const resp = await callCoreRpc<unknown>({
    method: 'openhuman.memory_list_documents',
    params: { namespace },
  });
  // Unwrap envelope: registry returns { data: { documents: [...] }, meta: {...} }
  if (resp && typeof resp === 'object' && !Array.isArray(resp) && 'data' in resp) {
    return (resp as Record<string, unknown>).data;
  }
  return resp;
}

export async function memoryListNamespaces(): Promise<string[]> {
  if (!isTauri()) {
    throw new Error('Not running in Tauri');
  }
  const resp = await callCoreRpc<{ data?: { namespaces?: string[] }; namespaces?: string[] }>({
    method: 'openhuman.memory_list_namespaces',

View on GitHub (pinned to 7491200858)

Solutions

  1. Run inside the Tauri desktop host: pnpm dev:app.
  2. Mock the Tauri core API in tests and stub the memory_list_documents envelope.
  3. Check isTauri() before fetching documents; render an empty/desktop-only state otherwise.
  4. Start memory polling only after the app reports core/IPC readiness.

Example fix

// before
const docs = await memoryListDocuments(ns); // throws in browser

// after
const docs = isTauri() ? await memoryListDocuments(ns) : undefined;
Defensive patterns

Strategy: validation

Validate before calling

const docs = isTauri() ? await memoryListDocuments(namespace) : undefined;

Type guard

const isDocumentsEnvelope = (v: unknown): v is { documents: unknown[] } =>
  !!v && typeof v === 'object' && Array.isArray((v as { documents?: unknown[] }).documents);

Try / catch

try { const docs = await memoryListDocuments(ns); }
catch (e) { if (e instanceof Error && e.message === 'Not running in Tauri') return; throw e; }

Prevention

When it happens

Trigger: A memory/sources screen calling memoryListDocuments(namespace) under the bare Vite dev server; a jsdom test rendering it without '@tauri-apps/api/core' mocks; the first poll of a memory hook landing before the bridge is injected at startup.

Common situations: Browser-based UI development (pnpm dev) of memory views; unit tests forgetting Tauri mocks; hooks that start polling on mount regardless of environment.

Related errors


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