{"record":{"id":"4b22a5f448c49218","repo":"stablyai/orca","slug":"result-error","errorCode":null,"errorMessage":"${result.error}","messagePattern":"\\$\\{result\\.error\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mobile/src/tasks/composer-source-base-resolve.ts","lineNumber":42,"sourceCode":"}): Promise<GitHubPrStartPoint> {\n  const { client, repoId, prNumber, headRefName, baseRefName, isCrossRepository } = args\n  const response = await client.sendRequest(\n    'worktree.resolvePrBase',\n    {\n      repo: `id:${repoId}`,\n      prNumber,\n      ...(headRefName ? { headRefName } : {}),\n      ...(baseRefName ? { baseRefName } : {}),\n      ...(isCrossRepository !== undefined ? { isCrossRepository } : {})\n    },\n    { timeoutMs: 30_000 }\n  )\n  if (!response.ok) {\n    throw new Error(response.error.message)\n  }\n  const result = (response as RpcSuccess).result as GitHubPrStartPoint | { error: string }\n  if ('error' in result) {\n    throw new Error(result.error)\n  }\n  return result\n}\n\n// Resolves a GitLab MR's base via worktree.resolveMrBase.\nexport async function resolveComposerMrBase(args: {\n  client: RpcClient\n  repoId: string\n  mrIid: number\n  sourceBranch?: string\n  targetBranch?: string\n  isCrossRepository?: boolean\n}): Promise<ComposerHostedBase> {\n  const { client, repoId, mrIid, sourceBranch, targetBranch, isCrossRepository } = args\n  const response = await client.sendRequest(\n    'worktree.resolveMrBase',\n    {\n      repo: `id:${repoId}`,","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/tasks/composer-source-base-resolve.ts#L24-L60","documentation":"The worktree.resolvePrBase RPC succeeded at the transport level (response.ok === true) but the result body is { error: string }, the runtime's soft-error convention for provider-level failures. As the source comment notes, the runtime returns this payload 'rather than an RPC error for provider failures.' This means the host reached GitHub but could not resolve a usable base branch for the PR.","triggerScenarios":"The PR was deleted or closed and its refs are gone; the PR is a fork and headRefName/baseRefName are stale or omitted; cross-repository metadata (isCrossRepository) is wrong; GitHub returned the PR but the base branch no longer exists in the repo.","commonSituations":"User selects a linked PR whose base branch was force-pushed away; a cross-repo fork PR whose parent was renamed; the host's cached PR data is stale relative to upstream; maintainer disabled fork access (maintainerCanModify revoked).","solutions":["Catch at the composer source-selection layer and show result.error verbatim — it carries the provider's reason (e.g. 'base branch not found').","Offer a manual base-branch picker as a fallback when the soft error is non-recoverable.","Re-fetch the PR's head/base ref names before retrying resolveComposerPrBase so isCrossRepository and refs are current.","If the error mentions permissions, direct the user to re-authorize GitHub on the desktop host."],"exampleFix":"// before\nconst result = (response as RpcSuccess).result as GitHubPrStartPoint | { error: string }\nif ('error' in result) {\n  throw new Error(result.error)\n}\n\n// after — distinguish soft provider error from success so the UI can offer manual base selection\nconst result = (response as RpcSuccess).result as GitHubPrStartPoint | { error: string }\nif ('error' in result) {\n  throw new ComposerBaseResolveError(result.error, { retryable: true })\n}","handlingStrategy":"try-catch","validationCode":"// Re-fetch current PR ref names before resolving to avoid stale-head/base\nconst pr = await client.sendRequest('github.workItem', { repo: `id:${repoId}`, number: prNumber })\nif (pr.ok && pr.result && !(pr.result as any).error) {\n  // ref names are fresh\n}","typeGuard":"function isGitHubPrStartPoint(r: unknown): r is GitHubPrStartPoint {\n  return !!r && typeof r === 'object' && 'baseBranch' in r && !('error' in r)\n}","tryCatchPattern":"try {\n  const base = await resolveComposerPrBase({ client, repoId, prNumber, headRefName, baseRefName })\n} catch (e) {\n  // Soft provider error — offer manual base selection\n  openManualBaseBranchPicker()\n}","preventionTips":["Always pass headRefName and baseRefName when known — omitting them forces the runtime to guess, increasing soft-error odds.","Set isCrossRepository explicitly for fork PRs to avoid wrong-base resolution.","Have a manual base-branch picker ready as a fallback for provider errors."],"tags":["github","worktree","provider-error","soft-error","mobile"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}