sxyazi/yazi · error · io::Error
Cannot write cache stamp
Error message
Cannot write cache stamp: {e} What it means
This io::Error wraps a failure while writing the encoded stamp bytes to the stamp entry path via Local::regular().write(). The OS error kind is preserved and its Display embedded as 'Cannot write cache stamp: {e}'. It is raised in Stamp::write after the stamp path is determined and data encoded successfully.
Solutions
- Create the cache/stamp parent directory before writing (ensure it exists and is writable)
- Check free disk space and quotas on the cache volume
- Fix permissions on the cache directory; retry the write after remediation
Example fix
// before
Stamp::write(cha, url).await?;
// after
if let Some(path) = url.stamp_entry() {
if let Some(parent) = path.parent() { tokio::fs::create_dir_all(parent).await?; }
}
Stamp::write(cha, url).await?; Defensive patterns
Strategy: try-catch
Validate before calling
if let Some(path) = url.stamp_entry() {
if let Some(parent) = path.parent() {
tokio::fs::create_dir_all(parent).await?;
}
} Type guard
fn stamp_writable(path: &Path) -> bool {
path.parent().map(|p| p.is_dir()).unwrap_or(false)
} Try / catch
match Stamp::write(cha, url).await {
Ok(()) => (),
Err(e) if e.kind() == io::ErrorKind::StorageFull => warn_disk_full(),
Err(e) => return Err(e),
} Prevention
- Create the cache parent directory before writing stamps
- Monitor free disk space on the cache volume
- Check cache dir permissions after system/account changes
When it happens
Trigger: Calling Stamp::write(cha, url) when url.stamp_entry() yields a path whose parent directory does not exist, is not writable, or the async write fails (disk full, permissions, I/O error).
Common situations: Cache directory deleted at runtime; read-only cache mount; disk quota/full disk while caching a downloaded remote file; permission misconfiguration on XDG cache dir.
Related errors
- Cannot read cache stamp
- Not a local URL
- Not a local URL
- Cache stamp does not match entry
- Cache stamp does not match target
AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-02).
Data as JSON: /api/errors/1539abca2e228f8f.
Report an issue: GitHub.
Appendix: source
Thrown at yazi-vfs/src/stamp.rs:61
let stamp = Self::read_at(&path).await?;
let name = StrandCow::with(dir.loc().kind(), stamp.name()).map_err(io::Error::other)?;
let url = dir.try_join(name)?;
if url.hash_u128_str(&mut [0; Self::SIG_LEN]).as_bytes() != key.encoded_bytes() {
return Err(io::Error::new(io::ErrorKind::InvalidData, "Cache stamp does not match entry"));
}
Ok(url)
}
pub async fn write(cha: Cha, url: Url<'_>) -> io::Result<()> {
let path = url.stamp_entry().ok_or_else(|| io::Error::other("Cannot determine cache stamp"))?;
let data = Self::encode(cha, url)?;
Local::regular(&path)
.write(data)
.await
.map_err(|e| io::Error::new(e.kind(), format!("Cannot write cache stamp: {e}")))
}
fn encode(cha: Cha, url: Url) -> io::Result<Vec<u8>> {
let name = url.name().ok_or_else(|| io::Error::other("URL has no filename"))?;
let mut buf = Vec::with_capacity(Self::SIG_LEN + name.len());
buf.extend_from_slice(cha.hash_u128_str(&mut [0; Self::SIG_LEN]).as_bytes());
buf.extend_from_slice(name.encoded_bytes());
Ok(buf)
}
pub fn validate(&self, cha: Cha, url: Url) -> io::Result<()> {
let name = url.name().ok_or_else(|| io::Error::other("URL has no filename"))?;
if self.name() != name.encoded_bytes() {
return Err(io::Error::new(io::ErrorKind::InvalidData, "Cache stamp does not match target"));
}
View on GitHub (pinned to 8ebf930f17)