{"record":{"id":"1efb238d552c8290","repo":"stablyai/orca","slug":"response-error-message","errorCode":null,"errorMessage":"${response.error.message}","messagePattern":"\\$\\{response\\.error\\.message\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mobile/src/browser/MobileBrowserPane.tsx","lineNumber":576,"sourceCode":"      params: Record<string, unknown> = {},\n      opts: { showBusy?: boolean; suppressError?: boolean; timeoutMs?: number } = {}\n    ): Promise<unknown | null> => {\n      const base = pageParams()\n      if (!client || !base) {\n        return null\n      }\n      if (opts.showBusy) {\n        busyRef.current = true\n        setBusy(true)\n      }\n      try {\n        const response = await client.sendRequest(\n          method,\n          { ...base, ...params },\n          { timeoutMs: opts.timeoutMs ?? 15_000 }\n        )\n        if (!response.ok) {\n          throw new Error((response as RpcFailure).error.message)\n        }\n        setError(null)\n        return (response as RpcSuccess).result\n      } catch (err) {\n        const message = browserErrorMessage(err, 'Browser command failed')\n        if (!opts.suppressError && shouldSurfaceBrowserError(message)) {\n          setError(message)\n        }\n        return null\n      } finally {\n        if (opts.showBusy) {\n          busyRef.current = false\n          setBusy(false)\n        }\n      }\n    },\n    [client, pageParams]\n  )","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/browser/MobileBrowserPane.tsx#L558-L594","documentation":"Generic browser-command dispatcher in the mobile browser pane: sendBrowserRequest() forwards an arbitrary method+params to the host with a 15s default timeout and throws when the RPC returns ok=false. The thrown message is the host's raw error.message; the surrounding catch maps it through browserErrorMessage() and shouldSurfaceBrowserError() to decide UI surfacing, returning null on failure.","triggerScenarios":"Any browser.* RPC (browser.goto, browser.click, browser.scroll, etc.) returns ok=false — page not found, navigation timeout, browser backend (Chromium/puppeteer) crashed on the host, invalid params, or a timeout exceeding 15s/opts.timeoutMs.","commonSituations":"Navigating to an unreachable URL, a host browser backend that crashed or OOMed, slow page loads exceeding the 15s default, or a worktree/pageId mismatch after the host recycled the browser session.","solutions":["Pass a larger opts.timeoutMs for slow navigations (navigateToAddress already uses 30s).","Set opts.suppressError=true for best-effort commands where failure should not set the error banner.","Check the host browser backend is alive (restart the host if Chromium crashed).","Validate the URL via normalizeBrowserUrl before calling goto."],"exampleFix":"// before\nif (!response.ok) {\n  throw new Error((response as RpcFailure).error.message)\n}\n\n// after — keep the code for branching in the caller\nif (!response.ok) {\n  const e = (response as RpcFailure).error\n  throw new Error(`${e.code ? '[' + e.code + '] ' : ''}${e.message}`)\n}","handlingStrategy":"try-catch","validationCode":"// Validate URL and session before dispatching\nif (!client || !pageParams()) return null\nif (method === 'browser.goto') {\n  const url = normalizeBrowserUrl(params.url as string)\n  if (!url) { setError('Enter a valid URL.'); return null }\n}","typeGuard":"function isBrowserRpcSuccess(r: RpcSuccess | RpcFailure): r is RpcSuccess {\n  return r.ok\n}","tryCatchPattern":"try {\n  const response = await client.sendRequest(method, { ...base, ...params }, { timeoutMs: opts.timeoutMs ?? 15_000 })\n  if (!response.ok) throw new Error((response as RpcFailure).error.message)\n  return (response as RpcSuccess).result\n} catch (err) {\n  const message = browserErrorMessage(err, 'Browser command failed')\n  if (!opts.suppressError && shouldSurfaceBrowserError(message)) setError(message)\n  return null\n}","preventionTips":["Pass larger timeoutMs for navigation; 15s is too tight for slow pages.","Use suppressError=true for best-effort commands (scroll, hover).","Route user-visible text through browserErrorMessage for consistent tone."],"tags":["mobile","rpc","browser","puppeteer","fallback-message"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}