{"record":{"id":"d80a1bb442c9f985","repo":"tinyhumansai/openhuman","slug":"not-running-in-tauri-d80a1b","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/taskSources.ts","lineNumber":131,"sourceCode":"  connectionId?: string;\n  /** Executor routing (G7): personality/skill/agent handle to pre-assign. */\n  assignedExecutor?: string;\n}\n\nexport interface TaskSourceAddParams {\n  provider: TaskSourceProvider;\n  filter: TaskSourceFilter;\n  name?: string;\n  connection_id?: string;\n  interval_secs?: number;\n  target?: TaskSourceTarget;\n  max_tasks_per_fetch?: number;\n  assigned_executor?: string;\n}\n\nfunction ensureTauri(): void {\n  if (!isTauri()) {\n    throw new Error('Not running in Tauri');\n  }\n}\n\nexport async function openhumanTaskSourcesList(): Promise<TaskSource[]> {\n  ensureTauri();\n  return await callCoreRpc<TaskSource[]>({ method: 'openhuman.task_sources_list' });\n}\n\nexport async function openhumanTaskSourcesGet(id: string): Promise<TaskSource> {\n  ensureTauri();\n  return await callCoreRpc<TaskSource>({ method: 'openhuman.task_sources_get', params: { id } });\n}\n\nexport async function openhumanTaskSourcesAdd(params: TaskSourceAddParams): Promise<TaskSource> {\n  ensureTauri();\n  return await callCoreRpc<TaskSource>({\n    method: 'openhuman.task_sources_add',\n    params: params as unknown as Record<string, unknown>,","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/app/src/utils/tauriCommands/taskSources.ts#L113-L149","documentation":"This throw comes from `ensureTauri()`, the shared precondition helper in taskSources.ts used by every task-source CRUD wrapper (`openhumanTaskSourcesList`, `openhumanTaskSourcesGet`, and the rest of that family). One central guard covers the whole surface: `isTauri()` false — plain browser, jsdom test, or the CEF bootstrap gap where `window.__TAURI_INTERNALS__.invoke` is not yet a function — means the local core RPC relay is unreachable, so each wrapper throws before sending its `openhuman.task_sources_*` request.","triggerScenarios":"Opening the task sources settings page (which immediately calls `openhumanTaskSourcesList()`) in the Vite browser preview; any subsequent get/create/update/delete of a task source in web mode; unit tests of task-source components with the default non-Tauri mock environment; a page load whose initial list call races the CEF bridge injection.","commonSituations":"Browser-first development of the integrations/task-sources screens; jsdom tests producing this rejection from the initial list effect; web previews or Storybook harnesses that mount the settings page.","solutions":["Develop and verify task-source management inside the desktop shell (`pnpm dev:app`).","Skip the initial list fetch and render an empty/desktop-only state when `!isTauri()`.","Mock `isTauri` true and stub `callCoreRpc` (or mock the whole taskSources module) in tests.","Catch at the data-loading effect and degrade gracefully rather than surfacing the throw.","If task sources must be managed against a remote core from the web, relax `ensureTauri()` to also allow an active transport (it is only needed for the local relay), keeping the helper for shell-only commands."],"exampleFix":"// before\nuseEffect(() => {\n  openhumanTaskSourcesList().then(setSources);\n}, []);\n\n// after\nuseEffect(() => {\n  if (!isTauri()) {\n    setSources([]); // web preview: task-source RPC needs the desktop shell\n    return;\n  }\n  openhumanTaskSourcesList().then(setSources).catch(console.error);\n}, []);","handlingStrategy":"validation","validationCode":"import { isTauri } from '../utils/tauriCommands/common';\n\nif (!isTauri()) {\n  setSources([]); // task-source CRUD all goes through ensureTauri()\n  return;\n}\nconst sources = await openhumanTaskSourcesList();","typeGuard":"function isNotInTauriError(e: unknown): e is Error {\n  return e instanceof Error && e.message === 'Not running in Tauri';\n}","tryCatchPattern":"try {\n  const sources = await openhumanTaskSourcesList();\n} catch (e) {\n  if (e instanceof Error && e.message === 'Not running in Tauri') {\n    setDesktopOnly(true);\n    return;\n  }\n  throw e;\n}","preventionTips":["Remember the guard is shared: list, get, create, update, delete all throw the same way — gate the whole settings screen once.","Skip the initial list effect in web mode instead of catching per action.","Mock isTauri and callCoreRpc (or the whole taskSources module) in tests.","Keep task-source forms disabled in web previews so users never compose input that cannot be saved."],"tags":["tauri","environment-guard","frontend","task-sources","settings","ipc"],"backgroundTag":"not-running-in-tauri","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}