can1357/oh-my-pi · error · Error
GitHub release ${expectedTag} has ${matches.length} assets n
Error message
GitHub release ${expectedTag} has ${matches.length} assets named ${binaryName} What it means
After collecting assets whose `name` equals the expected platform binary name, the code requires exactly one match. Zero matches mean the binary was never uploaded for this platform; more than one means duplicate/ambiguous assets. The count is embedded in the message so the failure mode is immediately clear.
Source
Thrown at packages/coding-agent/src/cli/update-cli.ts:214
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}`);
}
const asset = matches[0];
if (!isRecord(asset) || asset.state !== "uploaded") {
throw new Error(`GitHub release asset ${binaryName} is not fully uploaded`);
}
if (typeof asset.size !== "number" || !Number.isSafeInteger(asset.size) || asset.size <= 0) {
throw new Error(`GitHub release asset ${binaryName} has an invalid size`);
}
if (typeof asset.digest !== "string") {
throw new Error(`GitHub release asset ${binaryName} has no digest`);
}
const digest = /^sha256:([0-9a-f]{64})$/i.exec(asset.digest)?.[1];
if (!digest) {
throw new Error(`GitHub release asset ${binaryName} has an unsupported digest`);
}
const expectedUrl = `https://github.com/${REPO}/releases/download/${expectedTag}/${binaryName}`;View on GitHub (pinned to 9690622007)
Solutions
- Inspect the release's assets on https://github.com/<owner>/<repo>/releases/tags/<tag> and compare exact filenames against the expected binaryName.
- If the binary is missing, re-run or fix the release upload workflow for your platform.
- If duplicates exist, delete the stale duplicate asset and re-publish, or cut a new release.
- Wait for the release process to finish if it is still mid-publish, then retry.
Example fix
// before: release missing the platform asset (only linux-x64 uploaded)
assets: [{ name: "omp-linux-x64", ... }]
// after: upload all platform binaries
assets: [
{ name: "omp-linux-x64", ... },
{ name: "omp-linux-arm64", ... },
{ name: "omp-darwin-arm64", ... }
] Defensive patterns
Strategy: validation
Validate before calling
const matching = (release.assets as { name?: unknown }[]).filter(a => a?.name === binaryName);
if (matching.length !== 1) {
console.error(`Release ${tag} has ${matching.length} assets named ${binaryName}; available: ${(release.assets as { name?: unknown }[]).map(a => a?.name).join(", ")}`);
process.exit(1);
} Type guard
function isUniqueAsset(assets: unknown[], binaryName: string): boolean {
return assets.filter(a => typeof a === "object" && a !== null && (a as { name?: unknown }).name === binaryName).length === 1;
} Try / catch
try {
await update();
} catch (err) {
const m = err instanceof Error ? err.message : "";
if (/has \d+ assets named /.test(m)) {
console.error(`Binary asset problem for your platform: ${m}. Inspect the release assets on GitHub.`);
} else throw err;
} Prevention
- Keep release upload workflows atomic: upload all platform binaries before publishing.
- Disable or clean up re-upload retries that can create duplicate asset names.
- Pin CI to a naming convention and assert all expected platform filenames exist before publish.
When it happens
Trigger: resolveReleaseBinaryAsset filters release.assets by `asset.name === binaryName` and throws whenever matches.length !== 1 — i.e. the release has no asset with that exact name, or two or more assets share it.
Common situations: Running the updater on a platform whose binary was not included in the release (e.g. arm64 build missing), a release workflow re-run that uploaded the same filename twice, a typo or naming-scheme change in the CI upload step, or the user's binaryName not matching the released naming convention.
Related errors
- GitHub release asset ${binaryName} is not fully uploaded
- GitHub release asset ${binaryName} has an invalid size
- GitHub release ${expectedTag} has no asset list
- GitHub release asset ${binaryName} has no digest
- GitHub release asset ${binaryName} has an unsupported digest
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6018c4027f4439af.
Report an issue: GitHub.