can1357/oh-my-pi · error · Error
Invalid GitHub release metadata
Error message
Invalid GitHub release metadata
What it means
During a binary update, resolveReleaseBinaryAsset validates the GitHub API release payload before selecting a download asset. If the response is not a plain object (isRecord fails) it throws this error. This guards against API errors, proxies returning HTML/error bodies, or unexpected payload shapes being treated as release metadata.
Source
Thrown at packages/coding-agent/src/cli/update-cli.ts:197
return majorVersion(release.version) > majorVersion(currentVersion);
}
/**
* Select and validate the binary asset from GitHub release metadata.
*
* Draft releases are always rejected. Prereleases are rejected unless
* `options.allowPrerelease` is set, which the canary channel passes: canary
* GitHub releases are published as prereleases, and the exact-tag match below
* still pins the download to the specific requested version.
*/
export function resolveReleaseBinaryAsset(
release: unknown,
expectedTag: string,
binaryName: string,
options: { allowPrerelease?: boolean } = {},
): ReleaseBinaryAsset {
if (!isRecord(release)) {
throw new Error("Invalid GitHub release metadata");
}
if (release.tag_name !== expectedTag) {
throw new Error(`GitHub release tag mismatch: expected ${expectedTag}`);
}
if (release.draft !== false) {
throw new Error(`GitHub release ${expectedTag} is a draft, not a published release`);
}
if (release.prerelease !== false && !options.allowPrerelease) {
throw new Error(`GitHub release ${expectedTag} is a prerelease; only canary updates install prerelease assets`);
}
if (!Array.isArray(release.assets)) {
throw new Error(`GitHub release ${expectedTag} has no asset list`);
}
const matches = release.assets.filter(asset => isRecord(asset) && asset.name === binaryName);
if (matches.length !== 1) {
throw new Error(`GitHub release ${expectedTag} has ${matches.length} assets named ${binaryName}`);
}View on GitHub (pinned to 9690622007)
Solutions
- Check connectivity to api.github.com and any proxy configuration (HTTP_PROXY/HTTPS_PROXY).
- Wait for GitHub rate limits to reset (check `gh api rate_limit` or response headers) and retry the update.
- Retry later if GitHub status shows an incident.
- Verify the updater is pointed at the correct repository/releases endpoint; update manually by downloading the release binary from github.com releases as a fallback.
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(releaseApiUrl, { headers: { accept: "application/vnd.github+json" } });
const release = await res.json();
if (typeof release !== "object" || release === null || Array.isArray(release) || typeof release.tag_name !== "string") {
throw new Error("Release endpoint returned non-object payload; check proxy/rate limits");
} Type guard
function isRelease(v: unknown): v is { tag_name: string; draft: boolean; prerelease: boolean; assets: unknown[] } {
return typeof v === "object" && v !== null && !Array.isArray(v)
&& typeof (v as any).tag_name === "string"
&& typeof (v as any).draft === "boolean"
&& typeof (v as any).prerelease === "boolean";
} Try / catch
try {
const asset = resolveReleaseBinaryAsset(release, expectedTag, binaryName);
} catch (err) {
if (err instanceof Error && err.message === "Invalid GitHub release metadata") {
console.error("GitHub API payload was not a release object — check proxy/rate limit/status.");
}
throw err;
} Prevention
- Authenticate GitHub API calls to raise rate limits (GITHUB_TOKEN).
- Bypass HTML-injecting corporate proxies for api.github.com.
- Check https://www.githubstatus.com before release-day updates.
- Validate the payload shape yourself before handing it to the resolver.
When it happens
Trigger: GitHub API returning a non-JSON or non-object body (rate-limit JSON parsed elsewhere, proxy/HTML error page, network middleware), a schema change in the releases endpoint, or a cached/garbage response handed to the resolver.
Common situations: Corporate proxy intercepting api.github.com; GitHub rate limiting (403 body shapes); running the updater behind a mirror that does not faithfully proxy the API; temporary GitHub incidents.
Related errors
- GitHub release tag mismatch: expected ${expectedTag}
- GitHub release ${expectedTag} is a draft, not a published re
- GitHub release ${expectedTag} is a prerelease; only canary u
- Provider ${providerName}: "api" is required when registering
- Provider ${providerName}, model ${modelDef.id}: no "api" spe
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/72d20f37fc181ce2.
Report an issue: GitHub.