jdx/mise · error
brew-cask:{}: cask metadata has no sha256
Error message
brew-cask:{}: cask metadata has no sha256 What it means
Every archive-backed cask must carry a sha256 for integrity verification. After downloading, mise matches on the cask's sha256 field: 'no_check' skips verification, a hex digest is verified, and an absent value is a hard error — mise refuses to install unverified archives. This protects against installing tampered or truncated downloads when cask metadata is incomplete.
Source
Thrown at src/system/packages/brew/cask/fetch.rs:258
let url_hash = &hash::hash_sha256_to_str(&cask.url)[..12];
let archive = cache_dir.join(format!(
"{}-{}-{url_hash}-{filename}",
cask.token, cask.version
));
if !archive.exists() {
HTTP.download_file(&cask.url, &archive, pr).await?;
// Strip macOS quarantine so it doesn't propagate into extracted/copied artifacts.
let _ = std::process::Command::new("xattr")
.args(["-d", "com.apple.quarantine"])
.arg(&archive)
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status();
}
match cask.sha256.as_deref() {
Some("no_check") => {}
Some(sha256) => hash::ensure_checksum(&archive, sha256, pr, "sha256")?,
None => bail!("brew-cask:{}: cask metadata has no sha256", cask.token),
}
Ok(archive)
}
pub(super) fn extract_archive(
cask: &Cask,
archive: &Path,
pr: Option<&dyn SingleReport>,
) -> Result<PathBuf> {
let extract_dir = crate::dirs::CACHE
.join("system-brew")
.join("cask-extract")
.join(format!("{}-{}", cask.token, cask.version));
file::remove_all(&extract_dir)?;
file::create_dir_all(&extract_dir)?;
let filename = archive
.file_name()
.and_then(|f| f.to_str())View on GitHub (pinned to afd2eddd3a)
Solutions
- Add the correct sha256 digest to the cask metadata (compute with `shasum -a 256 <file>` on the official artifact).
- If upstream genuinely publishes no checksum, set sha256 to the literal string 'no_check' to opt out explicitly — understanding verification is then skipped.
- Refresh the cask metadata from the official Homebrew API, which always supplies sha256, rather than a partial tap copy.
Example fix
// before
{"token": "myapp", "url": "https://example.com/myapp.zip"}
// after
{"token": "myapp", "url": "https://example.com/myapp.zip", "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"} Defensive patterns
Strategy: validation
Validate before calling
// verify cask JSON carries a checksum before installing
const meta = JSON.parse(fs.readFileSync(caskJson, 'utf8'));
if (!meta.sha256) throw new Error(`cask ${meta.token} missing sha256`); Type guard
function hasSha256(c) { return typeof c.sha256 === 'string' && c.sha256.length > 0; } Prevention
- Always include sha256 (or explicit 'no_check') in hand-written cask JSON.
- Compute the digest with `shasum -a 256` on the exact published artifact.
- Prefer official-API cask metadata over partial tap copies.
When it happens
Trigger: fetch_archive is called (via fetch_and_stage) for a cask whose metadata JSON has no sha256 key and whose URL is not a git URL; i.e. any archive cask installed from metadata lacking a checksum.
Common situations: Third-party taps with hand-written cask JSON missing the sha256 field; locally modified cask metadata where the checksum was deleted; tooling that regenerated cask JSON and dropped the checksum.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- brew-cask:{}: cask metadata has no sha256
- remote cache blob pack failed digest verification
- verified checksum file digest does not match existing checks
- Invalid checksum: {platform_key}
- Checksum mismatch for file {}: Expected: {algo}:{checksum} A
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/e21204af92282436.
Report an issue: GitHub.