sxyazi/yazi · error

invalid file type: {value:04o}

Error message

invalid file type: {value:04o}

What it means

ChaMode::try_from validates a raw st_mode value by masking off permission bits and checking that the remaining file-type bits match a known type (regular, dir, link, block, char, sock, fifo). Any other bit pattern is rejected with the octal value included in the message. This guards against corrupt or fabricated mode data entering the type system.

Source

Thrown at yazi-fs/src/cha/mode.rs:75

			_ => &ChaType::Unknown,
		}
	}
}

impl TryFrom<u16> for ChaMode {
	type Error = anyhow::Error;

	fn try_from(value: u16) -> Result<Self, Self::Error> {
		let me = Self::from_bits(value).ok_or_else(|| anyhow!("invalid file mode: {value:04o}"))?;
		match me & Self::T_MASK {
			Self::T_FILE
			| Self::T_DIR
			| Self::T_LINK
			| Self::T_BLOCK
			| Self::T_CHAR
			| Self::T_SOCK
			| Self::T_FIFO => Ok(me),
			_ => bail!("invalid file type: {value:04o}"),
		}
	}
}

#[cfg(unix)]
impl From<ChaMode> for std::fs::Permissions {
	fn from(value: ChaMode) -> Self {
		use std::os::unix::fs::PermissionsExt;

		Self::from_mode(value.bits() as _)
	}
}

impl ChaMode {
	// Convert a file mode to a string representation
	#[cfg(unix)]
	#[allow(clippy::collapsible_else_if)]
	pub(crate) fn permissions(self, dummy: bool) -> [u8; 10] {

View on GitHub (pinned to 5f901b886b)

Solutions

  1. Inspect the octal value in the message; verify which file-type bits it carries and where the value came from.
  2. Only pass full stat st_mode values (with S_IFMT type bits) into ChaMode::try_from, never permission-only values.
  3. Sanitize/validate external or cached mode data before conversion; treat failure as corrupt and re-fetch via stat.

Example fix

// before
let mode = ChaMode::try_from(perm_bits_only)?;
// after
let mode = ChaMode::try_from(raw_st_mode)?; // full mode incl. S_IFMT type bits
Defensive patterns

Strategy: validation

Validate before calling

fn is_known_mode(value: u32) -> bool {
    matches!(value & libc::S_IFMT, libc::S_IFREG | libc::S_IFDIR | libc::S_IFLNK | libc::S_IFBLK | libc::S_IFCHR | libc::S_IFSOCK | libc::S_IFIFO)
}

Try / catch

let mode = ChaMode::try_from(raw).with_context(|| format!("bad mode {raw:04o} from {source:?}"))?;

Prevention

When it happens

Trigger: Constructing a ChaMode from a raw mode value whose file-type bits are not one of S_IFREG/S_IFDIR/S_IFLNK/S_IFBLK/S_IFCHR/S_IFSOCK/S_IFIFO — e.g. passing a value already masked incorrectly or a mode from a non-POSIX source.

Common situations: Reading mode fields from external/serialized data (plugin-provided data, cache files) that is corrupt or from a different OS encoding; accidentally passing permission bits only (masked away type bits -> zero) into the constructor.

Related errors


AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02). Data as JSON: /api/errors/12e66edd48587949. Report an issue: GitHub.