{"record":{"id":"011a3322ffec8b55","repo":"can1357/oh-my-pi","slug":"github-release-tag-mismatch-expected-expectedta","errorCode":null,"errorMessage":"GitHub release tag mismatch: expected ${expectedTag}","messagePattern":"GitHub release tag mismatch: expected (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/update-cli.ts","lineNumber":200,"sourceCode":"/**\n * Select and validate the binary asset from GitHub release metadata.\n *\n * Draft releases are always rejected. Prereleases are rejected unless\n * `options.allowPrerelease` is set, which the canary channel passes: canary\n * GitHub releases are published as prereleases, and the exact-tag match below\n * still pins the download to the specific requested version.\n */\nexport function resolveReleaseBinaryAsset(\n\trelease: unknown,\n\texpectedTag: string,\n\tbinaryName: string,\n\toptions: { allowPrerelease?: boolean } = {},\n): ReleaseBinaryAsset {\n\tif (!isRecord(release)) {\n\t\tthrow new Error(\"Invalid GitHub release metadata\");\n\t}\n\tif (release.tag_name !== expectedTag) {\n\t\tthrow new Error(`GitHub release tag mismatch: expected ${expectedTag}`);\n\t}\n\tif (release.draft !== false) {\n\t\tthrow new Error(`GitHub release ${expectedTag} is a draft, not a published release`);\n\t}\n\tif (release.prerelease !== false && !options.allowPrerelease) {\n\t\tthrow new Error(`GitHub release ${expectedTag} is a prerelease; only canary updates install prerelease assets`);\n\t}\n\tif (!Array.isArray(release.assets)) {\n\t\tthrow new Error(`GitHub release ${expectedTag} has no asset list`);\n\t}\n\n\tconst matches = release.assets.filter(asset => isRecord(asset) && asset.name === binaryName);\n\tif (matches.length !== 1) {\n\t\tthrow new Error(`GitHub release ${expectedTag} has ${matches.length} assets named ${binaryName}`);\n\t}\n\n\tconst asset = matches[0];\n\tif (!isRecord(asset) || asset.state !== \"uploaded\") {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/update-cli.ts#L182-L218","documentation":"resolveReleaseBinaryAsset pins the download to an exact release tag. After basic shape validation it compares the payload's tag_name with the expected tag; any mismatch throws this error naming the expected tag. This prevents installing binaries from a different release than the one the update flow resolved.","triggerScenarios":"The release metadata's tag_name differs from expectedTag — e.g. a redirect/mirror serving a different (older/newer) release, a race where the release was re-tagged or replaced between lookup and validation, or passing the wrong expectedTag to the resolver.","commonSituations":"Updating through a GitHub mirror/proxy that caches a different release; release re-tagging by maintainers; concurrent update channels (stable vs canary) pointing at different tags; stale CDN cache.","solutions":["Re-run the update command to re-fetch fresh release metadata.","Clear/inspect any proxy or CDN cache in front of api.github.com if you route through one.","Confirm the intended channel (stable/canary) — canary expects a specific prerelease tag.","As a fallback, download the correct release binary manually from the GitHub releases page and install it directly."],"exampleFix":"null","handlingStrategy":"type-guard","validationCode":"if (release?.tag_name !== expectedTag) {\n  console.warn(`Mirror/cache drift: got ${release?.tag_name}, want ${expectedTag}`);\n}","typeGuard":"function hasExpectedTag(v: unknown, expectedTag: string): v is { tag_name: string; draft: boolean; prerelease: boolean; assets: unknown[] } {\n  return typeof v === \"object\" && v !== null && (v as any).tag_name === expectedTag;\n}","tryCatchPattern":"try {\n  const asset = resolveReleaseBinaryAsset(release, expectedTag, binaryName);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"GitHub release tag mismatch\")) {\n    console.error(\"Stale mirror/cache or re-tagged release; refetch metadata and retry.\");\n  }\n  throw err;\n}","preventionTips":["Fetch release metadata fresh immediately before validating (no long-lived cache).","Avoid third-party mirrors that may serve different releases.","Re-run the update after a maintainer re-tags a release.","Pin the channel explicitly so stable and canary never cross tags."],"tags":["github","update","versioning","tag-mismatch"],"backgroundTag":"release-tag-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}