sxyazi/yazi · error · io::Error

Cannot read cache stamp: {e}

Error message

Cannot read cache stamp: {e}

What it means

This io::Error wraps a failure while reading the cache stamp file at a given path via Local::regular().read(). The original OS error kind is preserved, and its Display is embedded as 'Cannot read cache stamp: {e}'. It means the stamp file itself could not be read (missing, permissions, I/O failure), not that its contents were bad.

Source

Thrown at yazi-vfs/src/stamp.rs:25

impl Stamp {
	const SIG_LEN: usize = 26;

	pub async fn read<U>(url: U) -> io::Result<Self>
	where
		U: AsUrl,
	{
		let path =
			url.as_url().stamp_entry().ok_or_else(|| io::Error::other("Cannot determine cache stamp"))?;

		Self::read_at(&path).await
	}

	async fn read_at(path: &Path) -> io::Result<Self> {
		let data = Local::regular(path)
			.read()
			.await
			.map_err(|e| io::Error::new(e.kind(), format!("Cannot read cache stamp: {e}")))?;

		Self::try_from(data)
			.map_err(|e| io::Error::new(e.kind(), format!("Cannot parse cache stamp: {e}")))
	}

	pub async fn resolve<U, S>(dir: U, key: S) -> io::Result<UrlBuf>
	where
		U: AsUrl,
		S: AsStrand,
	{
		let dir = dir.as_url();
		let key = key.as_strand();

		let mut path =
			dir.auth().stamp_root().ok_or_else(|| io::Error::other("Cannot determine stamp root"))?;
		path.push(key.as_os()?);

		let stamp = Self::read_at(&path).await?;

View on GitHub (pinned to 8ebf930f17)

Solutions

  1. Recreate the cache entry (re-download / rewrite the stamp) instead of treating it as fatal — a missing stamp is usually recoverable
  2. Check permissions and existence of the stamp file path before reading
  3. Verify the cache directory is on a healthy, writable filesystem

Example fix

// before
let stamp = Stamp::resolve(dir, key).await?;
// after
let stamp = match Stamp::resolve(dir, key).await {
    Ok(s) => s,
    Err(e) if e.kind() == io::ErrorKind::NotFound => re_download_and_write_stamp().await?,
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: fallback

Validate before calling

match tokio::fs::metadata(&stamp_path).await {
    Ok(m) if m.is_file() => {},
    _ => { /* treat as cache miss: re-download */ }
}

Type guard

fn stamp_readable(path: &Path) -> bool {
    std::fs::File::open(path).map(|_| true).unwrap_or(false)
}

Try / catch

match Stamp::resolve(dir, key).await {
    Ok(url) => url,
    Err(e) if e.kind() == io::ErrorKind::NotFound || e.kind() == io::ErrorKind::PermissionDenied => cache_miss_fallback(),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling Stamp::read_at (via Stamp::resolve or any consumer of the stamp cache) when the stamp file does not exist, lacks read permission, or the underlying file read fails asynchronously.

Common situations: Cache directory cleaned or partially deleted while Yazi is running; a downloaded entry's stamp file removed by a cleaner; permission changes on the cache directory; disk I/O errors.

Related errors


AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-02). Data as JSON: /api/errors/a731bb3151b30771. Report an issue: GitHub.