{"record":{"id":"95edca51e34b05af","repo":"tinyhumansai/openhuman","slug":"model-testing-is-only-available-in-the-desktop-app","errorCode":null,"errorMessage":"Model testing is only available in the desktop app.","messagePattern":"Model testing is only available in the desktop app\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"app/src/services/api/aiSettingsApi.ts","lineNumber":810,"sourceCode":"/** Fetch BYO provider auth failures recorded this process, keyed by slug. */\nexport async function loadProviderAuthErrors(): Promise<ProviderAuthError[]> {\n  if (!isTauri()) {\n    return [];\n  }\n  const res = await callCoreRpc<{ result: { errors: ProviderAuthError[] } }>({\n    method: 'openhuman.inference_provider_auth_errors',\n    params: {},\n  });\n  return res?.result?.errors ?? [];\n}\n\nexport async function testProviderModel(\n  workload: WorkloadId,\n  provider: string,\n  prompt = 'Hello world'\n): Promise<ProviderModelTestResult> {\n  if (!isTauri()) {\n    throw new Error('Model testing is only available in the desktop app.');\n  }\n  const res = await callCoreRpc<{ result: ProviderModelTestResult }>({\n    method: 'openhuman.inference_test_provider_model',\n    params: { workload, provider, prompt },\n    timeoutMs: PROVIDER_MODEL_TEST_TIMEOUT_MS,\n  });\n  if (!res?.result) {\n    throw new Error(\n      `Model test RPC returned no result for ${workload} via ${provider} (openhuman.inference_test_provider_model).`\n    );\n  }\n  return res.result;\n}\n\n// ─── Local provider façade (Ollama install / detect / model manage) ───────\n\n/** Snapshot of the Ollama daemon + installed-model state for the AI panel. */\nexport interface LocalProviderSnapshot {","sourceCodeStart":792,"sourceCodeEnd":828,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/app/src/services/api/aiSettingsApi.ts#L792-L828","documentation":"Thrown by testProviderModel() when isTauri() is false, i.e. the code is not running inside the Tauri desktop shell. The 'openhuman.inference_test_provider_model' RPC is relayed through the Tauri IPC command relay_http_rpc, which only exists when the webview is hosted by app/src-tauri. In a plain browser (Vite dev server, web preview) or the Vitest harness there is no IPC bridge, so the call is refused up front rather than failing obscurely later.","triggerScenarios":"Running `pnpm dev` (Vite-only) and clicking Test model in the AI settings panel; opening the built UI in a normal browser; unit tests that invoke testProviderModel without mocking isTauri.","commonSituations":"Developers doing fast frontend iteration with the browser dev server forget that model testing shells out through Tauri; CI/storybook-style web previews that render the settings screen; a test harness that stubs callCoreRpc but not isTauri.","solutions":["Run the full desktop shell for model testing: `pnpm dev:app` (Tauri dev) instead of `pnpm dev`.","In tests, mock the tauri guard: vi.mock('../utils/tauriCommands/common', () => ({ isTauri: () => true, ... })) before asserting RPC behavior.","In UI code, disable/hide the Test button when !isTauri() so users never reach the throw."],"exampleFix":"// before\n{isOpen && <button onClick={() => testProviderModel(workload, provider)}>Test</button>}\n\n// after\n{isOpen && (\n  <button disabled={!isTauri()} title={isTauri() ? undefined : 'Desktop app only'}\n          onClick={() => testProviderModel(workload, provider)}>Test</button>\n)}","handlingStrategy":"type-guard","validationCode":"import { isTauri } from '../utils/tauriCommands/common';\n\nconst canTestModels = isTauri();\nif (!canTestModels) {\n  // hide/disable the Test button; do not call testProviderModel\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = await testProviderModel(workload, provider);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('only available in the desktop app')) {\n    setNotice('Model testing requires the desktop app.');\n  } else throw e;\n}","preventionTips":["Gate desktop-only controls on isTauri() at render time, not at call time.","Use `pnpm dev:app` when exercising Tauri-bridged RPCs.","Mock isTauri in Vitest before asserting RPC behavior."],"tags":["tauri","environment-check","inference","desktop-only"],"backgroundTag":"platform-not-supported","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}