{"record":{"id":"ecc421d3c28feefb","repo":"stablyai/orca","slug":"waiting-for-desktop-ecc421","errorCode":null,"errorMessage":"Waiting for desktop...","messagePattern":"Waiting for desktop\\.\\.\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"mobile/src/session/use-mobile-diff-review-comment-actions.ts","lineNumber":67,"sourceCode":"    currentItem,\n    queue,\n    filteredQueue,\n    filter,\n    currentIndex,\n    composer,\n    composerBody,\n    setScreenState,\n    setCurrentIndex,\n    setComposer,\n    setComposerBody,\n    setActionError,\n    setShowCompletion\n  } = input\n\n  const persistMetadata = useCallback(\n    async (comments: readonly DiffComment[], reviewState: MobileDiffReviewState) => {\n      if (!client || connState !== 'connected') {\n        throw new Error('Waiting for desktop...')\n      }\n      const response = await client.sendRequest('worktree.set', {\n        worktree: `id:${worktreeId}`,\n        diffComments: comments,\n        mobileDiffReview: reviewState\n      })\n      if (!response.ok) {\n        throw new Error(response.error?.message || 'Failed to save review state')\n      }\n    },\n    [client, connState, worktreeId]\n  )\n\n  const updateReadyState = useCallback(\n    (updater: (state: Extract<ReviewScreenState, { kind: 'ready' }>) => ReviewScreenState) => {\n      setScreenState((prev) => (prev.kind === 'ready' ? updater(prev) : prev))\n    },\n    [setScreenState]","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/session/use-mobile-diff-review-comment-actions.ts#L49-L85","documentation":"Guard thrown by `persistMetadata` (saves diff comments + review state via `worktree.set`) when the mobile client has no live RPC client or is not `connected`. It blocks the optimistic write so the host is not called with a dead transport.","triggerScenarios":"client is null (never paired / disconnected) or connState is anything other than 'connected' (connecting, handshaking, reconnecting, auth-failed, disconnected). Any comment add/edit/delete or mark-reviewed that triggers persistence while in those states.","commonSituations":"User edits a comment during a brief reconnect window; relay dropped and connState is reconnecting; first-paint before the transport finished handshaking; auth-failed after token expiry.","solutions":["Wait for the connection to return to 'connected'.","The optimistic UI change will have been rolled back - re-apply after reconnect.","Re-pair if auth-failed.","Check network/relay reachability."],"exampleFix":"// before\nif (!client || connState !== 'connected') {\n  throw new Error('Waiting for desktop...')\n}\n// after - queue the write and replay once connected\nif (!client || connState !== 'connected') {\n  enqueuePendingMetadata(comments, reviewState)\n  throw new Error('Waiting for desktop...')\n}","handlingStrategy":"validation","validationCode":"if (!client || connState !== 'connected') {\n  setActionError('Waiting for desktop...')\n  return\n}","typeGuard":null,"tryCatchPattern":"try {\n  await saveCommentsAndReviewState(comments, reviewState)\n} catch (err) {\n  if ((err as Error).message === 'Waiting for desktop...') {\n    // keep local optimistic change; UI already shows waiting\n  } else throw err\n}","preventionTips":["Disable the comment save button until connState==='connected'.","Show a connection badge on the review screen.","Queue mutations during reconnect and replay on 'connected'."],"tags":["connection","guard","diff-review","mobile"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}