{"record":{"id":"493b50a67eababe2","repo":"jdx/mise","slug":"local-cas-blob-failed-digest-verification","errorCode":null,"errorMessage":"local CAS blob failed digest verification: {}","messagePattern":"local CAS blob failed digest verification: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/mise-cache-core/src/local.rs","lineNumber":49,"sourceCode":"    /// Resolve the storage path for a validated digest.\n    pub fn path_for(&self, digest: &CacheDigest) -> Result<PathBuf> {\n        digest.validate()?;\n        Ok(self\n            .root\n            .join(\"cas/v1\")\n            .join(&digest.algorithm)\n            .join(&digest.hash[..2])\n            .join(format!(\"{}-{}\", digest.hash, digest.size)))\n    }\n\n    /// Find and verify a stored object.\n    pub fn find(&self, digest: &CacheDigest) -> Result<Option<PathBuf>> {\n        let path = self.path_for(digest)?;\n        if !path.exists() {\n            return Ok(None);\n        }\n        if !digest.matches_file(&path)? {\n            bail!(\n                \"local CAS blob failed digest verification: {}\",\n                path.display()\n            );\n        }\n        Ok(Some(path))\n    }\n\n    /// Atomically store bytes after verifying their declared digest.\n    pub fn store_bytes(&self, digest: &CacheDigest, bytes: &[u8]) -> Result<PathBuf> {\n        if !digest.matches_bytes(bytes)? {\n            bail!(\"bytes do not match the declared CAS digest\");\n        }\n        self.store_with(digest, |temporary| {\n            temporary.write_all(bytes)?;\n            Ok(())\n        })\n    }\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/crates/mise-cache-core/src/local.rs#L31-L67","documentation":"`LocalCas::find` located the file at its content-addressed path (`cas/v1/<algo>/<hash[0..2]>/<hash>-<size>`) but re-hashing the file no longer matches the digest encoded in the path. The CAS treats this as corruption: the blob is not returned and the error names the offending path. Because paths derive from digests, something must have mutated the file after it was stored.","triggerScenarios":"Any `find`/`store_file` call that hits a CAS entry whose on-disk contents were changed: another process (editor, antivirus, backup or cleanup tool, user) modified or truncated files under the cache root; bit rot or filesystem corruption; a foreign file placed at the digest path by a different cache layout or version.","commonSituations":"Hand-editing or sparse-truncating files under the cache root; failing disks; sharing one cache directory between incompatible tool versions; cleanup utilities that touch files they should not.","solutions":["Delete the offending blob named in the error (or the whole `cas/v1` subtree) - the next run recomputes and re-stores it.","Run disk diagnostics (SMART, fsck) if corruption recurs.","Ensure nothing outside mise writes into the cache root, and exclude it from antivirus/backup tools that rewrite files.","In calling code, treat `find` errors as cache misses: recompute and `store_bytes` to heal the entry."],"exampleFix":"// before: propagate the corruption error\nlet path = cas.find(&digest)?.unwrap();\n\n// after: treat a corrupt blob as a miss and heal it\nlet path = match cas.find(&digest) {\n    Ok(Some(path)) => path,\n    _ => cas.store_bytes(&digest, &recompute())?,\n};","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let path = match cas.find(&digest) {\n    Ok(Some(path)) => path,\n    Ok(None) => cas.store_bytes(&digest, &produce())?,\n    Err(err) => {\n        warn!(\"corrupt CAS blob, healing: {err}\");\n        cas.store_bytes(&digest, &produce())? // recompute and overwrite by re-storing\n    }\n};","preventionTips":["Treat CAS find errors as cache misses and recompute; never propagate corruption to users.","Keep the cache root owned by one tool; exclude it from editors, cleaners, and antivirus.","Monitor for repeat corruption on the same path - that indicates failing hardware."],"tags":["local-cache","cas","checksum-mismatch","disk-corruption","rust"],"backgroundTag":"checksum-mismatch","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}