{"record":{"id":"78854f8e395b117b","repo":"stablyai/orca","slug":"source-control-action-failed","errorCode":null,"errorMessage":"Source control action failed","messagePattern":"Source control action failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mobile/src/session/use-mobile-diff-review-git-actions.ts","lineNumber":37,"sourceCode":"export function useMobileDiffReviewGitActions(input: GitActionsInput) {\n  const { client, connState, worktreeId, queue, setActionError, setBusyAction, loadReviewData } =\n    input\n\n  const runGitMutation = useCallback(\n    async (method: GitMutationMethod, item: MobileDiffReviewQueueItem) => {\n      if (!client || connState !== 'connected') {\n        setActionError('Waiting for desktop...')\n        return\n      }\n      setBusyAction(`${method}:${item.filePath}`)\n      setActionError(null)\n      try {\n        const response = await client.sendRequest(method, {\n          worktree: `id:${worktreeId}`,\n          filePath: item.filePath\n        })\n        if (!response.ok) {\n          throw new Error(response.error?.message || 'Source control action failed')\n        }\n        triggerSuccess()\n        await loadReviewData()\n      } catch (err) {\n        triggerError()\n        setActionError(err instanceof Error ? err.message : 'Source control action failed')\n      } finally {\n        setBusyAction(null)\n      }\n    },\n    [client, connState, loadReviewData, setActionError, setBusyAction, worktreeId]\n  )\n\n  const stageReviewedFiles = useCallback(async () => {\n    if (!client || connState !== 'connected') {\n      setActionError('Waiting for desktop...')\n      return\n    }","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/session/use-mobile-diff-review-git-actions.ts#L19-L55","documentation":"Thrown (then caught locally) when a git mutation RPC - git.stage, git.unstage, etc. (GitMutationMethod) - returns ok:false for a single file. The host's error.message is preferred. The local catch sets actionError and triggers an error haptic; it does NOT propagate.","triggerScenarios":"Host git operation fails for the file path - path no longer in the index, git lockfile contention, merge conflict state, or permission. Called from per-file stage/unstage buttons.","commonSituations":"File changed/disappeared between status fetch and the stage call; .git/index.lock held by another process; file in a conflict the mutation cannot resolve; host git binary error.","solutions":["Refresh the review data (loadReviewData) to get fresh status.","Check for a stale git lockfile on the host.","Retry the single-file action.","Inspect the host git error in logs."],"exampleFix":"// before\nif (!response.ok) {\n  throw new Error(response.error?.message || 'Source control action failed')\n}\n// after\nif (!response.ok) {\n  throw new RpcMethodError(method, response.error)\n}","handlingStrategy":"try-catch","validationCode":"if (!client || connState !== 'connected') {\n  setActionError('Waiting for desktop...')\n  return\n}","typeGuard":"function isRpcFailure(r: RpcResponse): r is RpcFailure {\n  return r.ok === false\n}","tryCatchPattern":"try {\n  await runGitMutation(method, item)\n} catch (err) {\n  setActionError(err instanceof Error ? err.message : 'Source control action failed')\n}","preventionTips":["Reload review data after any failed git mutation.","Avoid batching stage calls while a git operation is in progress on the host.","Show the host git message verbatim so users can act on it."],"tags":["rpc","git","source-control","diff-review","mobile"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}