{"record":{"id":"a568e678daaef364","repo":"stablyai/orca","slug":"auth","errorCode":"auth","errorMessage":"jira_summary_lookup:auth","messagePattern":"jira_summary_lookup:auth","errorType":"error_code","errorClass":"JiraSummaryLookupError","httpStatus":null,"severity":"error","filePath":"src/main/jira/issues.ts","lineNumber":679,"sourceCode":"      return mapped\n    } catch (error) {\n      console.warn('[jira] getIssue media load failed:', error)\n      return mapJiraIssue(entry.site, issue)\n    }\n  }\n  return null\n}\n\nexport async function getIssueSummary(\n  key: string,\n  siteId: string,\n  signal?: AbortSignal\n): Promise<JiraIssue | null> {\n  let entries: JiraClientForSite[]\n  try {\n    entries = getClients(siteId)\n  } catch (error) {\n    throw new JiraSummaryLookupError('auth', error)\n  }\n  const entry = entries.find((candidate) => candidate.site.id === siteId)\n  if (!entry) {\n    throw new JiraSummaryLookupError('disconnected')\n  }\n\n  return withJiraDeadline(signal, ISSUE_SUMMARY_TIMEOUT_MS, async (requestSignal) => {\n    await acquire(requestSignal)\n    try {\n      const params = new URLSearchParams({ fields: ISSUE_SUMMARY_FIELDS.join(',') })\n      const issue = await settleJiraSummaryRead(\n        jiraRequest<JiraRecord>(\n          entry,\n          `${apiBasePath(entry.site)}/issue/${encodeURIComponent(key)}?${params.toString()}`,\n          { signal: requestSignal }\n        ),\n        requestSignal\n      )","sourceCodeStart":661,"sourceCodeEnd":697,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/jira/issues.ts#L661-L697","documentation":"Thrown by getIssueSummary at the start when getClients(siteId) itself throws. This wraps the underlying error as a JiraSummaryLookupError with code 'auth', because getClients throws when credentials cannot be loaded or decrypted for the site. The .code property and the 'jira_summary_lookup:auth' message prefix let callers discriminate it from other lookup outcomes.","triggerScenarios":"The stored Jira access token for the site failed to decrypt (key rotation, corrupted site file), or the site configuration is invalid. getClients raises before any HTTP call is made, so this is purely a local credential/config failure.","commonSituations":"OS keychain/cryptographic key changed across machines or after OS update. Site file manually edited. Token expired and refresh failed during client construction.","solutions":["Reconnect the Jira site to re-store fresh credentials.","Verify the site entry in the Jira site file is intact and the encryption key is available.","Check getClients' underlying error (passed as cause) for decryption details.","Catch via getJiraSummaryLookupErrorCode(error) === 'auth' and prompt re-login."],"exampleFix":"// before\ntry { await getIssueSummary(key, siteId) } catch (e) { /* ? */ }\n// after\ntry {\n  await getIssueSummary(key, siteId)\n} catch (e) {\n  if (getJiraSummaryLookupErrorCode(e) === 'auth') await promptJiraReconnect(siteId)\n  else throw e\n}","handlingStrategy":"try-catch","validationCode":"try { getClients(siteId) } catch { await promptJiraReconnect(siteId); return }","typeGuard":"function isJiraSummaryAuthError(e: unknown): boolean {\n  return getJiraSummaryLookupErrorCode(e) === 'auth'\n}","tryCatchPattern":"try { return await getIssueSummary(key, siteId, signal) }\ncatch (e) {\n  if (getJiraSummaryLookupErrorCode(e) === 'auth') { await reconnectJira(siteId); return getIssueSummary(key, siteId, signal) }\n  throw e\n}","preventionTips":["Validate the Jira site credentials load before requesting summaries.","Handle code 'auth' with a reconnect prompt, not a generic retry.","Watch for key/encryption changes that break token decryption."],"tags":["jira","auth","summary-lookup","credentials"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}