{"record":{"id":"1c66ccd897573a79","repo":"can1357/oh-my-pi","slug":"github-release-expectedtag-is-a-draft-not-a-pu","errorCode":null,"errorMessage":"GitHub release ${expectedTag} is a draft, not a published release","messagePattern":"GitHub release (.+?) is a draft, not a published release","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/update-cli.ts","lineNumber":203,"sourceCode":" * 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\") {\n\t\tthrow new Error(`GitHub release asset ${binaryName} is not fully uploaded`);\n\t}\n\tif (typeof asset.size !== \"number\" || !Number.isSafeInteger(asset.size) || asset.size <= 0) {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/update-cli.ts#L185-L221","documentation":"Binary releases must be fully published; drafts have no final assets and are not downloadable by the general public. resolveReleaseBinaryAsset rejects any release whose draft flag is not exactly false with this error, even if the tag matches. This stops the updater from attempting to fetch assets that do not exist yet.","triggerScenarios":"Running an update while the target release is still in draft state on GitHub — typically right after maintainers created/uploaded the release but before publishing, or when a release was reverted back to draft.","commonSituations":"Updating minutes after a release announcement while assets are still being finalized; canary/stable channel pointed at an unpublished tag; release automation that uploads assets but has not hit publish yet.","solutions":["Wait until the release is published on the GitHub releases page and retry the update.","Verify on the releases page that the tag shows as published (not draft).","If you need pre-publish binaries, switch to the canary channel which installs prerelease assets once published as prereleases.","If it stays a draft indefinitely, report/check the release pipeline — the updater will never install from a draft."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (release.draft !== false) {\n  throw new Error(`${release.tag_name} is still a draft; wait for publish before updating`);\n}","typeGuard":"function isPublished(v: unknown): v is { tag_name: string; draft: false; prerelease: boolean; assets: unknown[] } {\n  return typeof v === \"object\" && v !== null && (v as any).draft === false;\n}","tryCatchPattern":"try {\n  const asset = resolveReleaseBinaryAsset(release, expectedTag, binaryName);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"is a draft\")) {\n    console.error(\"Release not published yet — retry later or pin to the previous release.\");\n  }\n  throw err;\n}","preventionTips":["Delay automated updates until a release has been public for a grace period (e.g. 30 min).","Check the releases page/API for draft status before upgrading on release day.","Pin updates to known-published tags in CI.","Use canary channel deliberately rather than racing fresh publishes."],"tags":["github","update","release","draft"],"backgroundTag":"unpublished-release","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}