sxyazi/yazi · warning

unknown image format

Error message

unknown image format

What it means

ImageInfo::new opens an image file with image::ImageReader::open and with_guessed_format; if the format cannot be determined (reader.format() returns None), the code wraps the failure into an IoError with InvalidData and the message "unknown image format". This means the file could be opened but its magic bytes/content don't match any decoder enabled in the image crate's feature set.

Solutions

  1. Check the file is actually an image before calling ImageInfo::new (read magic bytes or match the extension against known image formats).
  2. Enable the required decoder features of the `image` crate (e.g. webp, avif, jpeg, png) in Cargo.toml so with_guessed_format can identify the format.
  3. Verify the file is not truncated or corrupted (compare size/checksum against the source); re-download or regenerate it.
  4. Handle the error gracefully and fall back to a generic file preview instead of an image preview.

Example fix

// before
let info = ImageInfo::new(path).await?;
// after
let info = match ImageInfo::new(path).await {
    Ok(info) => info,
    Err(_) => return Ok(FilePreview::Generic), // not an image (or unsupported format)
};
Defensive patterns

Strategy: fallback

Validate before calling

// Rust
async fn is_probably_image(path: &Path) -> bool {
    let magic = |bytes: &[u8]| match bytes {
        [0x89, b'P', b'N', b'G', ..] | [0xFF, 0xD8, 0xFF, ..] | b"GIF8"[..].iter().copied().collect::<Vec<_>>().as_slice() if bytes.starts_with(b"GIF8") => true,
        [b'B', b'M', ..] | [b'R', b'I', b'F', b'F', ..] => true,
        _ => false,
    };
    tokio::fs::read(path).await.map(|b| b.len() > 11 && magic(&b)).unwrap_or(false)
}

Try / catch

match ImageInfo::new(path).await {
    Ok(info) => render(info),
    Err(e) if e.to_string().contains("unknown image format") => show_generic_preview(),
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling ImageInfo::new(path) on a file whose contents don't match a supported format: corrupt/truncated images, text or binary files with an image extension, or formats the image crate was compiled without (feature-gated decoders like webp/avif/heic).

Common situations: A previewer or plugin passes a user-supplied file to ImageInfo without checking the extension/magic bytes; a file is renamed to .png but isn't a PNG; the image crate features were trimmed so a valid image has no decoder; empty or zero-byte files.

Related errors


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

Appendix: source

Thrown at yazi-binding/src/image.rs:22

use mlua::{MetaMethod, UserData, UserDataFields, UserDataMethods};

// --- ImageInfo
#[derive(Clone, Copy)]
pub struct ImageInfo {
	format:      image::ImageFormat,
	width:       u32,
	height:      u32,
	color:       image::ColorType,
	orientation: Option<image::metadata::Orientation>,
}

impl ImageInfo {
	pub async fn new(path: PathBuf) -> image::ImageResult<Self> {
		tokio::task::spawn_blocking(move || {
			let reader = image::ImageReader::open(path)?.with_guessed_format()?;

			let Some(format) = reader.format() else {
				return Err(ImageError::IoError(std::io::Error::new(
					std::io::ErrorKind::InvalidData,
					"unknown image format",
				)));
			};

			let mut decoder = reader.into_decoder()?;
			let (width, height) = decoder.dimensions();
			Ok(Self {
				format,
				width,
				height,
				color: decoder.color_type(),
				orientation: decoder.orientation().ok(),
			})
		})
		.await
		.map_err(|e| ImageError::IoError(e.into()))?
	}

View on GitHub (pinned to 5f901b886b)