{"record":{"id":"67f479bd2786f352","repo":"oven-sh/bun","slug":"failed-to-fetch-sentry-issue-issueresponse-stat","errorCode":null,"errorMessage":"Failed to fetch Sentry issue: ${issueResponse.statusText}","messagePattern":"Failed to fetch Sentry issue: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/associate-issue-with-sentry.ts","lineNumber":38,"sourceCode":"    Authorization: `Bearer ${SENTRY_AUTH_TOKEN}`,\n  },\n});\nif (!response.ok) {\n  throw new Error(`Failed to fetch Sentry event: ${response.statusText}`);\n}\nconst json = await response.json();\nconst groupId = json?.groupId;\nif (!groupId) {\n  throw new Error(\"Missing groupId\");\n}\n\nconst issueResponse = await fetch(`https://sentry.io/api/0/issues/${groupId}/`, {\n  headers: {\n    Authorization: `Bearer ${SENTRY_AUTH_TOKEN}`,\n  },\n});\nif (!issueResponse.ok) {\n  throw new Error(`Failed to fetch Sentry issue: ${issueResponse.statusText}`);\n}\nconst { shortId, permalink } = await issueResponse.json();\nif (!shortId || !permalink) {\n  throw new Error(\"Missing shortId or permalink\");\n}\n\nconsole.log(`Sentry ID: ${shortId}`);\nconsole.log(`Sentry permalink: ${permalink}`);\n\nawait Bun.write(\"sentry-id.txt\", shortId);\nawait Bun.write(\"sentry-link.txt\", permalink);\n\nexport {};\n","sourceCodeStart":20,"sourceCodeEnd":52,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/scripts/associate-issue-with-sentry.ts#L20-L52","documentation":"The follow-up call GET /api/0/issues/<groupId>/ returned non-2xx. The groupId came from the previous event lookup, so failures here usually mean the group was deleted/merged, the token cannot see it, or the id is invalid for this org.","triggerScenarios":"Group resolved by the event endpoint but since deleted or merged in Sentry; token scopes allow event reads but not issue reads; groupId is from a different org.","commonSituations":"Issues merged in the Sentry dashboard between the two calls; token with narrow scopes; stale groupId from an old event.","solutions":["curl the issue URL with the same token and inspect the status and body","Widen the token scopes (org:read + project:read / event:read covering issues)","Handle 404 by skipping association for groups that no longer exist"],"exampleFix":"// before\nif (!issueResponse.ok) {\n  throw new Error(`Failed to fetch Sentry issue: ${issueResponse.statusText}`);\n}\n\n// after\nif (!issueResponse.ok) {\n  if (issueResponse.status === 404) {\n    console.log(`Sentry issue ${groupId} gone; skipping`);\n    process.exit(0);\n  }\n  throw new Error(`Failed to fetch Sentry issue: ${issueResponse.status} ${issueResponse.statusText}`);\n}","handlingStrategy":"try-catch","validationCode":"null","typeGuard":null,"tryCatchPattern":"try {\n  await fetchIssue(groupId);\n} catch (err) {\n  if (/Failed to fetch Sentry issue/.test(err.message) && /404/.test(err.message)) {\n    core.info('group no longer exists; skipping');\n    return;\n  }\n  throw err;\n}","preventionTips":["Treat merged/deleted Sentry groups (404) as expected skip conditions","Keep token scopes aligned with both endpoints used (events and issues)"],"tags":["sentry","http","api","authentication"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}