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

  1. Check connectivity to api.github.com and any proxy configuration (HTTP_PROXY/HTTPS_PROXY).
  2. Wait for GitHub rate limits to reset (check `gh api rate_limit` or response headers) and retry the update.
  3. Retry later if GitHub status shows an incident.
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/72d20f37fc181ce2. Report an issue: GitHub.