{"record":{"id":"80903ebffb7ccc8e","repo":"sxyazi/yazi","slug":"cache-stamp-does-not-match-target","errorCode":null,"errorMessage":"Cache stamp does not match target","messagePattern":"Cache stamp does not match target","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-vfs/src/stamp.rs","lineNumber":77,"sourceCode":"\t\t\t.write(data)\n\t\t\t.await\n\t\t\t.map_err(|e| io::Error::new(e.kind(), format!(\"Cannot write cache stamp: {e}\")))\n\t}\n\n\tfn encode(cha: Cha, url: Url) -> io::Result<Vec<u8>> {\n\t\tlet name = url.name().ok_or_else(|| io::Error::other(\"URL has no filename\"))?;\n\n\t\tlet mut buf = Vec::with_capacity(Self::SIG_LEN + name.len());\n\t\tbuf.extend_from_slice(cha.hash_u128_str(&mut [0; Self::SIG_LEN]).as_bytes());\n\t\tbuf.extend_from_slice(name.encoded_bytes());\n\n\t\tOk(buf)\n\t}\n\n\tpub fn validate(&self, cha: Cha, url: Url) -> io::Result<()> {\n\t\tlet name = url.name().ok_or_else(|| io::Error::other(\"URL has no filename\"))?;\n\t\tif self.name() != name.encoded_bytes() {\n\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidData, \"Cache stamp does not match target\"));\n\t\t}\n\n\t\tif self.sig() != cha.hash_u128_str(&mut [0; Self::SIG_LEN]) {\n\t\t\treturn Err(io::Error::new(\n\t\t\t\tio::ErrorKind::InvalidData,\n\t\t\t\t\"Remote file has changed since last download\",\n\t\t\t));\n\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","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-vfs/src/stamp.rs#L59-L95","documentation":"Returned by Stamp::validate when the stamp's recorded filename differs from the target URL's name. It is an InvalidData error indicating the cached stamp belongs to a different file than the URL being validated, so the cache entry must not be trusted.","triggerScenarios":"Calling stamp.validate(cha, url) where url.name() is None would already error earlier; the specific 'does not match target' fires when self.name() != name.encoded_bytes() — i.e., the stamp was written for a differently-named file than the URL supplied.","commonSituations":"Reusing a cached stamp across renamed files; mixing up cache entries after a remote rename; a bug where the wrong stamp file is looked up for a URL.","solutions":["Rewrite the stamp for the current URL via Stamp::write to resynchronize name and signature","Verify the stamp file being validated is the one derived from this URL (stamp_entry)","If the remote renamed the file, refresh the cache entry under the new name"],"exampleFix":"// before\nstamp.validate(cha, url)?;\n// after\nif let Err(e) = stamp.validate(cha, url) {\n    if e.kind() == io::ErrorKind::InvalidData { Stamp::write(cha, url.clone()).await?; }\n    else { return Err(e); }\n}","handlingStrategy":"validation","validationCode":"if let Some(name) = url.name() {\n    // name must equal the stamp's recorded name before validating\n    if stamp.name() != name.encoded_bytes() { /* regenerate stamp */ }\n}","typeGuard":"fn stamp_targets(stamp: &Stamp, url: &Url) -> bool {\n    url.name().map(|n| stamp.name() == n.encoded_bytes()).unwrap_or(false)\n}","tryCatchPattern":"match stamp.validate(cha, url.clone()) {\n    Ok(()) => (),\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => Stamp::write(cha, url).await?,\n    Err(e) => return Err(e),\n}","preventionTips":["Write a fresh stamp immediately after every download","Never reuse a stamp file across different URLs","Look up the stamp strictly via url.stamp_entry()"],"tags":["validation","cache","integrity","rust"],"backgroundTag":"cache-key-mismatch","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"}