{"record":{"id":"4318f0dbc6b047e3","repo":"sxyazi/yazi","slug":"invalid-cache-stamp","errorCode":null,"errorMessage":"Invalid cache stamp","messagePattern":"Invalid cache stamp","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-vfs/src/stamp.rs","lineNumber":103,"sourceCode":"\t\t}\n\t\tOk(())\n\t}\n\n\t#[inline]\n\tpub fn sig(&self) -> &str { unsafe { str::from_utf8_unchecked(&self.0[..Self::SIG_LEN]) } }\n\n\t#[inline]\n\tfn name(&self) -> &[u8] { &self.0[Self::SIG_LEN..] }\n}\n\nimpl TryFrom<Vec<u8>> for Stamp {\n\ttype Error = io::Error;\n\n\tfn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {\n\t\tlet (sig, _) = value\n\t\t\t.split_at_checked(Self::SIG_LEN)\n\t\t\t.filter(|(_, n)| !n.is_empty())\n\t\t\t.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, \"Invalid cache stamp\"))?;\n\n\t\tstr::from_utf8(sig).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;\n\t\tOk(Self(value))\n\t}\n}\n","sourceCodeStart":85,"sourceCodeEnd":109,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-vfs/src/stamp.rs#L85-L109","documentation":"Produced by TryFrom<Vec<u8>> for Stamp when the raw bytes cannot be split into a non-empty signature of SIG_LEN bytes plus a non-empty name — i.e., the buffer is too short or malformed, marked InvalidData with message 'Invalid cache stamp'.","triggerScenarios":"Stamp::try_from(bytes) (called from read_at) with a Vec shorter than SIG_LEN, exactly SIG_LEN with no name bytes, or an empty buffer — typically a truncated or empty stamp file.","commonSituations":"Crash or disk-full during Stamp::write leaving a 0-byte/partial file; a different stamp binary format written by another tool or version in the cache directory.","solutions":["Delete the malformed stamp file and regenerate it (re-download + Stamp::write)","Purge the whole cache directory to remove all corrupt stamps","Check for partial-write issues; ensure writes are atomic (write-temp-then-rename) if customizing"],"exampleFix":"// before\nlet stamp = Stamp::try_from(bytes)?;\n// after\nfn is_plausible_stamp(b: &[u8]) -> bool { b.len() > SIG_LEN }\nif !is_plausible_stamp(&bytes) { std::fs::remove_file(&stamp_path)?; return cache_miss(); }","handlingStrategy":"validation","validationCode":"let data = tokio::fs::read(&stamp_path).await?;\nlet ok = data.len() > Stamp::SIG_LEN && !data[Stamp::SIG_LEN..].is_empty();\nif !ok { std::fs::remove_file(&stamp_path).await.ok(); /* cache miss */ }","typeGuard":"fn is_valid_stamp_shape(data: &[u8]) -> bool {\n    data.split_at_checked(Stamp::SIG_LEN)\n        .map(|(_, name)| !name.is_empty())\n        .unwrap_or(false)\n}","tryCatchPattern":"match Stamp::try_from(data) {\n    Ok(s) => s,\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => { drop_corrupt_stamp(); cache_miss() },\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Delete 0-byte or suspiciously small stamp files","Avoid interrupting writes; prefer atomic temp-file-then-rename","Regenerate the cache after crashes"],"tags":["parsing","validation","cache","rust"],"backgroundTag":"cache-stamp-parse-failed","analyzedSha":"8ebf930f1796ae2076b7d6b0c5e93a1002c18134","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}