{"record":{"id":"bd791b0da93dfcde","repo":"stablyai/orca","slug":"response-error-message-fallbackmessage","errorCode":null,"errorMessage":"${response.error.message || fallbackMessage}","messagePattern":"\\$\\{response\\.error\\.message \\|\\| fallbackMessage\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mobile/src/browser/MobileBrowserPane.tsx","lineNumber":1380,"sourceCode":"): void {\n  for (const [index, layer] of layers.entries()) {\n    layer?.setNativeProps({ style: { opacity: index === visible ? 1 : 0 } })\n  }\n}\n\nfunction updateBrowserImageSource(image: Image | null, uri: string): void {\n  // Why: browser frames are large strings; mutating only the native Image\n  // source avoids re-rendering the whole tab view for every streamed frame.\n  const source = [{ uri }]\n  image?.setNativeProps({ source, src: source })\n}\n\nfunction assertRpcOk(\n  response: RpcSuccess | RpcFailure,\n  fallbackMessage: string\n): asserts response is RpcSuccess {\n  if (!response.ok) {\n    throw new Error(response.error.message || fallbackMessage)\n  }\n}\n\nfunction browserFrameMetadataEqual(\n  a: BrowserScreencastFrameMetadata | null,\n  b: BrowserScreencastFrameMetadata\n): boolean {\n  return (\n    a?.deviceWidth === b.deviceWidth &&\n    a?.deviceHeight === b.deviceHeight &&\n    a?.pageScaleFactor === b.pageScaleFactor\n  )\n}\n\nfunction browserErrorMessage(error: unknown, fallback: string): string {\n  return error instanceof Error && error.message ? error.message : fallback\n}\n","sourceCodeStart":1362,"sourceCodeEnd":1398,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/browser/MobileBrowserPane.tsx#L1362-L1398","documentation":"assertRpcOk() is a TypeScript assertion helper used by the mobile browser pane to narrow an RpcSuccess|RpcFailure to RpcSuccess. If the response is a failure it throws the host's error.message, falling back to a caller-supplied message (e.g. 'Browser frame metadata mismatch') when the host omitted the message. It exists so browser-frame code can use `assertRpcOk(resp, '...')` and then read `.result` type-safely.","triggerScenarios":"Any call site passing a response into assertRpcOk where the host returned ok=false — typically browser.navigate, screencast frame requests, or metadata fetches — with an optional empty error.message triggering the fallback.","commonSituations":"Host browser backend returned an error without a message string, a screencast session expired, or a navigation/zoom command was issued against a closed page.","solutions":["Catch at the call site and route through browserErrorMessage() for user-facing display.","Ensure the host always sets error.message on browser RPC failures so the fallback is never the user-visible text.","Retry the screencast/navigate after re-establishing the browser session if the page was closed."],"exampleFix":"// before\nfunction assertRpcOk(response, fallbackMessage) {\n  if (!response.ok) {\n    throw new Error(response.error.message || fallbackMessage)\n  }\n}\n\n// after — include error code and fallback context\nfunction assertRpcOk(response, fallbackMessage) {\n  if (!response.ok) {\n    const e = response.error\n    throw new Error(e.message || `${fallbackMessage}${e.code ? ' (code: ' + e.code + ')' : ''}`)\n  }\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isRpcSuccess(r: RpcSuccess | RpcFailure): r is RpcSuccess {\n  return r.ok\n}\n// Then: if (isRpcSuccess(response)) { /* use response.result */ } else { /* handle response.error */ }","tryCatchPattern":"try {\n  assertRpcOk(response, 'Browser frame metadata mismatch')\n  // ... use response.result\n} catch (err) {\n  setError(browserErrorMessage(err, 'Browser command failed'))\n}","preventionTips":["Prefer the type-guard form over throw-on-assert in hot paths to avoid exception cost.","Always pass a descriptive fallbackMessage specific to the call site.","Ensure the host populates error.message so the fallback rarely triggers."],"tags":["mobile","rpc","browser","type-guard","assertion"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}