sxyazi/yazi · error

directory is owned by uid but current uid is

Error message

directory {:?} is owned by uid {} but current uid is {}

What it means

create_owned_dir_blocking creates a directory intended to be private to the current user. After creating it, it stats the directory and rejects it with PermissionDenied if st_uid differs from the current uid, then enforces mode 0o700 via fchmod. The error protects against pre-existing directories planted by another user (e.g. a symlink/hardening attack or leftover dirs from a different account).

Solutions

  1. chown the directory back to the current user (sudo chown -R $USER:$USER <dir>) or simply remove it and let the app recreate it.
  2. Avoid running the application with sudo; if root is needed initially, fix ownership afterwards.
  3. Check the parent path in the error message for stale root-owned state in ~/.cache, ~/.config, or ~/.local/share.
Defensive patterns

Strategy: validation

Validate before calling

// shell: verify ownership before running
[ "$(stat -c %u ~/.config/yazi 2>/dev/null)" = "$(id -u)" ] || echo "fix ownership: sudo chown -R $(id -u):$(id -g) ~/.config/yazi"

Try / catch

if let Err(e) = create_owned_dir(&dir).await {
    if e.kind() == std::io::ErrorKind::PermissionDenied {
        eprintln!("{} is owned by another user; run: sudo chown -R $USER <dir>", dir.display());
    }
    return Err(e.into());
}

Prevention

When it happens

Trigger: Creating a config/cache/data directory whose path already exists and is owned by a different uid — e.g. the app was previously run as root (sudo), leaving ~/.config/yazi owned by root, and now a normal user runs the deserializer's over-hook / create_owned_dir.

Common situations: Running yazi once with sudo; Docker containers that started as root then switched user; NFS/shared filesystems where uid mapping differs; an admin pre-created the directory under a service account.

Related errors


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

Appendix: source

Thrown at yazi-fs/src/fns.rs:113

		use libc::{O_DIRECTORY, O_NOFOLLOW};
		use uzers::Users;
		use yazi_shared::USERS_CACHE;

		DirBuilder::new().mode(0o700).recursive(true).create(p)?;
		let dir = OpenOptions::new().read(true).custom_flags(O_DIRECTORY | O_NOFOLLOW).open(p)?;

		let mut stat: libc::stat = unsafe { mem::zeroed() };
		if unsafe { libc::fstat(dir.as_raw_fd(), &mut stat) } != 0 {
			return Err(io::Error::last_os_error());
		}

		// Reject directories not owned by the current user.
		let uid = USERS_CACHE.get_current_uid();
		if stat.st_uid != uid {
			return Err(io::Error::new(
				io::ErrorKind::PermissionDenied,
				format!("directory {:?} is owned by uid {} but current uid is {}", p, stat.st_uid, uid),
			));
		}

		// Enforce mode 0o700 via the fd.
		if unsafe { libc::fchmod(dir.as_raw_fd(), 0o700) } != 0 {
			return Err(io::Error::last_os_error());
		}

		Ok(())
	}
	#[cfg(not(unix))]
	{
		std::fs::DirBuilder::new().recursive(true).create(p)
	}
}

View on GitHub (pinned to 8ebf930f17)