{"record":{"id":"bc0ae8e337beed88","repo":"stablyai/orca","slug":"unexpected-linear-tasks-response","errorCode":null,"errorMessage":"Unexpected Linear tasks response","messagePattern":"Unexpected Linear tasks response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mobile/src/tasks/linear-mobile-issue-read.ts","lineNumber":38,"sourceCode":"\ntype LinearIssueReadEnvelope = {\n  items?: unknown\n}\n\nexport function extractLinearIssueReadItems(result: unknown): LinearMobileIssue[] {\n  if (Array.isArray(result)) {\n    return result as LinearMobileIssue[]\n  }\n\n  if (\n    result &&\n    typeof result === 'object' &&\n    Array.isArray((result as LinearIssueReadEnvelope).items)\n  ) {\n    return (result as { items: LinearMobileIssue[] }).items\n  }\n\n  throw new Error('Unexpected Linear tasks response')\n}\n","sourceCodeStart":20,"sourceCodeEnd":40,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/tasks/linear-mobile-issue-read.ts#L20-L40","documentation":"extractLinearIssueReadItems received a result from the Linear RPC that is neither a bare array nor an { items: [...] } envelope. The function accepts unknown (it is the raw RpcSuccess.result) and narrows through two shapes before throwing. This is a contract/shape mismatch: the desktop runtime returned a Linear payload the mobile parser does not recognize.","triggerScenarios":"The host's linear.searchIssues/linear.listIssues returned a paginated envelope without an items key (e.g. { nodes: [...] } or { data: { issues: [...] } }); the runtime wrapped the result in an extra layer; a version mismatch introduced a new envelope; the runtime returned an error-shaped object that still passed isRpcResponse.","commonSituations":"Desktop runtime updated its Linear integration to a new GraphQL response shape; mobile and desktop are on mismatched versions; the Linear workspace returned an empty/edge-case object; a relay in the middle altered the payload.","solutions":["Log the actual result shape (keys + typeof) when this throws so the envelope can be added to the narrower.","Extend extractLinearIssueReadItems to accept the new envelope (e.g. { nodes } or { data: { issues } }).","Degrade to an empty list with a visible warning rather than crashing the whole search panel.","Pin mobile and desktop to compatible versions until the contract is updated."],"exampleFix":"// before\nif (\n  result &&\n  typeof result === 'object' &&\n  Array.isArray((result as LinearIssueReadEnvelope).items)\n) {\n  return (result as { items: LinearMobileIssue[] }).items\n}\nthrow new Error('Unexpected Linear tasks response')\n\n// after — accept additional envelope shapes and degrade safely\nif (result && typeof result === 'object') {\n  const obj = result as Record<string, unknown>\n  const list = obj.items ?? obj.nodes ?? (obj.data as { issues?: unknown[] })?.issues\n  if (Array.isArray(list)) return list as LinearMobileIssue[]\n}\nreturn [] // graceful degradation instead of a crash","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isLinearResultArray(r: unknown): r is LinearMobileIssue[] {\n  return Array.isArray(r)\n}\n\nfunction isLinearEnvelope(r: unknown): r is { items: LinearMobileIssue[] } {\n  return !!r && typeof r === 'object' && Array.isArray((r as any).items)\n}","tryCatchPattern":"try {\n  const items = extractLinearIssueReadItems(result)\n} catch (e) {\n  console.error('Linear shape mismatch', Object.keys(result ?? {}))\n  return [] // graceful degradation\n}","preventionTips":["Log the result shape (typeof + keys) when the parser throws to diagnose envelope drift.","Coordinate Linear response-shape changes across mobile and desktop releases.","Degrade to [] instead of crashing the search panel on unknown shapes."],"tags":["linear","type-mismatch","contract","mobile","version-mismatch"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}