{"record":{"id":"f98159e6ece5aa40","repo":"stablyai/orca","slug":"envelope-error-message","errorCode":null,"errorMessage":"envelope.error.message","messagePattern":"envelope\\.error\\.message","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mobile/src/tasks/smart-source-search-requests.ts","lineNumber":66,"sourceCode":"  query: string,\n  state: MrStateFilter\n): Promise<GitLabWorkItem[]> {\n  const response = await client.sendRequest('gitlab.listWorkItems', {\n    repo: `id:${repoId}`,\n    state,\n    page: 1,\n    perPage: GITLAB_PER_PAGE,\n    query: query.trim() || undefined\n  })\n  if (!response.ok) {\n    throw new Error(response.error.message)\n  }\n  const envelope = (response as RpcSuccess).result as {\n    items: GitLabWorkItem[]\n    error?: { type?: string; message: string }\n  }\n  if (envelope.error?.type && envelope.error.type !== 'not_found') {\n    throw new Error(envelope.error.message)\n  }\n  return (envelope.items ?? []).map((item) => ({ ...item, repoId }))\n}\n\nexport async function searchLinearIssues(\n  client: RpcClient,\n  query: string,\n  linearWorkspaceId: string | null | undefined\n): Promise<LinearIssue[]> {\n  const trimmed = query.trim()\n  const response = trimmed\n    ? await client.sendRequest('linear.searchIssues', {\n        query: trimmed,\n        limit: LINEAR_LIMIT,\n        workspaceId: linearWorkspaceId ?? undefined\n      })\n    : await client.sendRequest('linear.listIssues', {\n        // Empty query lists the viewer's assigned issues, matching desktop's","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/tasks/smart-source-search-requests.ts#L48-L84","documentation":"The gitlab.listWorkItems RPC succeeded at transport level (response.ok === true) but the result envelope carries a non-not_found error: { items, error?: { type?, message } }. The code throws only when envelope.error.type exists and is not 'not_found'. This is the GitLab provider surfacing an auth, permission, or connection error as a soft envelope field rather than an RPC failure.","triggerScenarios":"The host's GitLab token lacks scope for the project; GitLab returned a 401/403 that the runtime normalized into the envelope; the GitLab instance is reachable but the API version is unsupported; a transient GitLab 5xx was wrapped as a generic error type.","commonSituations":"Host GitLab token scope reduced after the search was opened; GitLab project moved to private; self-hosted GitLab API version mismatch; GitLab instance overloaded returning 5xx.","solutions":["Inspect envelope.error.type to distinguish auth errors from transient ones.","For auth-type errors, surface 'Re-authorize GitLab on your computer' and return [].","For transient types, return [] and auto-retry on next query input.","Always preserve not_found as an empty result (the existing guard) — do not throw for it."],"exampleFix":"// before\nif (envelope.error?.type && envelope.error.type !== 'not_found') {\n  throw new Error(envelope.error.message)\n}\n\n// after — classify auth vs transient, degrade instead of throwing\nif (envelope.error?.type && envelope.error.type !== 'not_found') {\n  if (envelope.error.type === 'auth') {\n    return [] // UI shows 'Re-authorize GitLab' banner\n  }\n  throw new Error(envelope.error.message)\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isGitLabSoftError(r: unknown): r is { type: string; message: string } {\n  const env = r as { error?: { type?: string; message: string } }\n  return !!env.error?.type && env.error.type !== 'not_found'\n}","tryCatchPattern":"try {\n  const items = await searchGitLabItems(client, repoId, query, state)\n} catch (e) {\n  // envelope.error carries the provider reason\n  if (e.message.includes('auth')) {\n    showGitLabReauthBanner()\n  }\n  return []\n}","preventionTips":["Inspect envelope.error.type to distinguish auth errors from transient ones.","Always allow not_found to pass through as an empty result.","Surface auth-type soft errors as a re-authorize prompt, not a crash."],"tags":["gitlab","smart-source","soft-error","auth","mobile"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}