{"record":{"id":"9bad28b7370bcfa5","repo":"affaan-m/ECC","slug":"release-lookup-failed-response-status","errorCode":null,"errorMessage":"release lookup failed (${response.status})","messagePattern":"release lookup failed \\((.+?)\\)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/discord/release-announce.mjs","lineNumber":47,"sourceCode":"async function githubGraphql(query, variables) {\n  const response = await request('https://api.github.com/graphql', {\n    method: 'POST',\n    headers: { Authorization: `Bearer ${env.GITHUB_TOKEN}`, 'Content-Type': 'application/json' },\n    body: JSON.stringify({ query, variables }),\n  });\n  if (!response.ok) throw new Error(`GitHub GraphQL request failed (${response.status})`);\n  const payload = await response.json();\n  if (payload.errors) throw new Error('GitHub GraphQL returned errors');\n  return payload.data;\n}\n\nasync function releaseFromGitHub() {\n  const [owner, repo] = env.GITHUB_REPOSITORY.split('/');\n  const tag = env.RELEASE_TAG || env.GITHUB_REF_NAME;\n  const response = await request(`https://api.github.com/repos/${owner}/${repo}/releases/tags/${encodeURIComponent(tag)}`, {\n    headers: { Authorization: `Bearer ${env.GITHUB_TOKEN}`, Accept: 'application/vnd.github+json' },\n  });\n  if (!response.ok) throw new Error(`release lookup failed (${response.status})`);\n  return response.json();\n}\n\nasync function createOrFindReleaseDiscussion() {\n  const release = await releaseFromGitHub();\n  const [owner, name] = env.GITHUB_REPOSITORY.split('/');\n  const marker = releaseMarker(release.tag_name);\n  const data = await githubGraphql(\n    `query($owner:String!,$name:String!){repository(owner:$owner,name:$name){id discussionCategories(first:25){nodes{id name}}}}`,\n    { owner, name },\n  );\n  const repository = data.repository;\n  let cursor = null;\n  let existing = null;\n  for (let page = 0; page < 50 && !existing; page += 1) {\n    const pageData = await githubGraphql(\n      `query($owner:String!,$name:String!,$after:String){repository(owner:$owner,name:$name){discussions(first:100,after:$after,orderBy:{field:CREATED_AT,direction:DESC}){nodes{id title body url category{name}} pageInfo{hasNextPage endCursor}}}}`,\n      { owner, name, after: cursor },","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/discord/release-announce.mjs#L29-L65","documentation":"releaseFromGitHub fetches a GitHub release by tag via the REST API and throws this error when `response.ok` is false (any non-2xx status). The status code is embedded in the message to distinguish 404 (no release for that tag) from 401/403 (auth) and other failures.","triggerScenarios":"GET https://api.github.com/repos/{owner}/{repo}/releases/tags/{tag} returning 404 (no published release exists for RELEASE_TAG/GITHUB_REF_NAME), 401 (bad GITHUB_TOKEN), 403 (rate limited or forbidden), 422 (malformed tag).","commonSituations":"Running the announce script on a tag with only a draft release (drafts are not reachable by tag endpoint without push access/preview header); RELEASE_TAG env var mismatched with actual tag; token missing repo scope; tag name needing encodeURIComponent mismatches if env already encoded.","solutions":["Verify the tag actually has a published (non-draft) GitHub release: gh release view <tag>","Check the response status in the message: 404 -> fix tag/RELEASE_TAG or create the release; 401 -> fix GITHUB_TOKEN; 403 -> wait out rate limit or check token scopes","Ensure GITHUB_REPOSITORY is set correctly (owner/repo)","Print the response body for the detailed GitHub error before throwing"],"exampleFix":"// before\nif (!response.ok) throw new Error(`release lookup failed (${response.status})`);\n// after\nif (!response.ok) throw new Error(`release lookup failed (${response.status}): ${await response.text()}`);","handlingStrategy":"validation","validationCode":"// before running, verify the release exists\nconst [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');\nconst tag = process.env.RELEASE_TAG || process.env.GITHUB_REF_NAME;\nconst res = await fetch(`https://api.github.com/repos/${owner}/${repo}/releases/tags/${encodeURIComponent(tag)}`, { headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` } });\nif (res.status === 404) throw new Error(`No published release for tag ${tag} in ${owner}/${repo} — drafts are not returned by this endpoint`);","typeGuard":null,"tryCatchPattern":"try {\n  const release = await releaseFromGitHub();\n} catch (err) {\n  const m = /release lookup failed \\((\\d+)\\)/.exec(err.message);\n  if (m && m[1] === '404') throw new Error(`Release for tag not found; publish the release first: ${err.message}`);\n  throw err;\n}","preventionTips":["Publish the GitHub release (not draft) before announcing","Keep RELEASE_TAG in sync with the actual git tag / GITHUB_REF_NAME","Check gh release view <tag> locally before triggering the workflow","Include the response body in error messages for the real GitHub error"],"tags":["github-api","http","rest"],"backgroundTag":"http-error-response","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}