{"record":{"id":"8dddada686037de5","repo":"can1357/oh-my-pi","slug":"failed-to-fetch-github-release-metadata-respons","errorCode":null,"errorMessage":"Failed to fetch GitHub release metadata: ${response.statusText}","messagePattern":"Failed to fetch GitHub release metadata: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/update-cli.ts","lineNumber":277,"sourceCode":"\ttry {\n\t\tresponse = await fetchImpl(`${GITHUB_API}/repos/${REPO}/releases/tags/${encodeURIComponent(tag)}`, {\n\t\t\theaders,\n\t\t\tsignal: withTimeoutSignal(RELEASE_METADATA_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tif (isTimeoutError(err)) {\n\t\t\tthrow new Error(\"Timed out fetching GitHub release metadata after 30s\", { cause: err });\n\t\t}\n\t\tif (isUnsupportedProxyError(err)) throw new Error(unsupportedProxyMessage(), { cause: err });\n\t\tthrow err;\n\t}\n\tif ((response.status === 403 && !githubToken) || response.status === 429) {\n\t\tthrow new Error(\n\t\t\t\"GitHub API rate limit exceeded while fetching release metadata; retry later or set GITHUB_TOKEN or GH_TOKEN\",\n\t\t);\n\t}\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch GitHub release metadata: ${response.statusText}`);\n\t}\n\n\treturn resolveReleaseBinaryAsset(await response.json(), tag, binaryName, { allowPrerelease });\n}\n\nexport interface VerifiedBinaryDownloadOptions {\n\turl: string;\n\ttargetPath: string;\n\texpectedSize: number;\n\texpectedDigest: string;\n\tfetchImpl?: Fetch;\n}\n\n/**\n * Download a binary and verify its GitHub-reported size and SHA-256 digest.\n */\nexport async function downloadVerifiedBinary(options: VerifiedBinaryDownloadOptions): Promise<void> {\n\tconst fetchImpl = options.fetchImpl ?? fetch;","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/update-cli.ts#L259-L295","documentation":"Thrown by getReleaseBinaryAsset in packages/coding-agent/src/cli/update-cli.ts when the GitHub REST releases API responds with a non-OK status that is not the already-handled 403/429 rate-limit case. The updater needs release metadata (assets, digests) to locate the correct binary; without a 2xx response it cannot proceed. The HTTP statusText is embedded so the developer can see why GitHub rejected the request.","triggerScenarios":"Any non-ok GitHub API response during `omp update`: 404 when the resolved release tag or release object does not exist, 401 when GITHUB_TOKEN/GH_TOKEN is set but invalid or expired, 5xx when GitHub is having an incident, or 403 with a token set (rate-limit-with-token branch only handles 403 without a token).","commonSituations":"Running an update against a fork or private repo where the release is not published; a stale/expired GitHub PAT in the environment; GitHub status degradation; requesting a --canary tag that was deleted.","solutions":["Verify the release/tag actually exists on the repo the updater targets (e.g. check https://github.com/<owner>/<repo>/releases).","If GITHUB_TOKEN or GH_TOKEN is set, validate it: `gh api user` or `curl -H \"Authorization: Bearer $GITHUB_TOKEN\" https://api.github.com` — replace or unset if invalid.","If the error is transient (5xx), wait and retry the update later.","Check https://www.githubstatus.com for ongoing GitHub API incidents."],"exampleFix":"// before: expired token in shell profile\nexport GITHUB_TOKEN=ghp_oldexpiredtoken\n// after\nunset GITHUB_TOKEN  # or export GITHUB_TOKEN=$(gh auth token)","handlingStrategy":"try-catch","validationCode":"const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;\nif (token) {\n  const res = await fetch(\"https://api.github.com/user\", { headers: { Authorization: `Bearer ${token}` } });\n  if (!res.ok) console.warn(\"GITHUB_TOKEN is invalid; unset it before updating\");\n}","typeGuard":"function isGitHubApiFailure(err: unknown): err is Error & { message: string } {\n  return err instanceof Error && err.message.startsWith(\"Failed to fetch GitHub release metadata\");\n}","tryCatchPattern":"try {\n  await runUpdate();\n} catch (err) {\n  if (isGitHubApiFailure(err)) {\n    // inspect statusText in err.message; wait for GitHub incident or fix GITHUB_TOKEN, then retry\n  } else throw err;\n}","preventionTips":["Keep GITHUB_TOKEN fresh (use `gh auth token`) or unset it when not needed","Check githubstatus.com before large update rollouts","Pin updates to tags you have verified exist in the releases page"],"tags":["network","github-api","http-error","update-cli"],"backgroundTag":"http-request-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}