can1357/oh-my-pi · error · Error
GitHub release asset ${binaryName} has no digest
Error message
GitHub release asset ${binaryName} has no digest What it means
The updater verifies downloads against the asset's sha256 digest, which GitHub exposes on the asset record as a `digest` string. If the field is absent, integrity verification is impossible, so the update is refused rather than installing an unverified binary.
Source
Thrown at packages/coding-agent/src/cli/update-cli.ts:225
}
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}`;
if (asset.browser_download_url !== expectedUrl) {
throw new Error(`GitHub release asset ${binaryName} has an unexpected download URL`);
}
return {
url: expectedUrl,
size: asset.size,
digest: `sha256:${digest.toLowerCase()}`,
};
}
View on GitHub (pinned to 9690622007)
Solutions
- Confirm you are sending the supported API version header (X-GitHub-Api-Version: 2022-11-28) and refetch.
- Check the asset in the GitHub API response — if digest is absent, re-upload the asset so GitHub computes a digest.
- Retry later: digest population can briefly lag upload on very fresh releases.
- Avoid proxies/interceptors that rewrite the response body.
Defensive patterns
Strategy: validation
Validate before calling
const asset = release.assets?.find(a => a?.name === binaryName);
if (typeof asset?.digest !== "string") {
console.warn("Asset has no digest; refusing unverified download.");
process.exit(1);
} Type guard
function hasDigest(asset: unknown): asset is { digest: string } {
return typeof (asset as { digest?: unknown })?.digest === "string";
} Try / catch
try {
await update();
} catch (err) {
if (err instanceof Error && err.message.includes("has no digest")) {
console.error("GitHub did not provide a checksum for this asset; update refused for safety. Re-upload the asset or retry later.");
} else throw err;
} Prevention
- Only download binaries whose published checksum you can verify.
- Re-upload stale assets created before GitHub populated digests.
- Send the 2022-11-28 API-version header so digest fields are present.
When it happens
Trigger: resolveReleaseBinaryAsset throws when the matched asset has `typeof asset.digest !== "string"` — the digest field is missing, null, or a non-string value.
Common situations: Releases created before GitHub started populating asset digests, custom upload tooling or API-created assets without digests, proxies stripping fields, or older pinned API versions that predate the digest field.
Related errors
- GitHub release asset ${binaryName} has an unsupported digest
- GitHub release asset ${binaryName} has an invalid size
- GitHub release ${expectedTag} has no asset list
- GitHub release ${expectedTag} has ${matches.length} assets n
- GitHub release asset ${binaryName} is not fully uploaded
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/55b27ae84d8f2136.
Report an issue: GitHub.