sxyazi/yazi · info · PeekError::Unexpected
Binary file
Error message
Binary file
What it means
The highlighter peeks files line by line and scans the inspected prefix with is_binary; as soon as a binary signature (NUL and similar bytes) is found it stops with Err(anyhow!("Binary file")) surfaced as a PeekError. This is intentional: syntax highlighting is refused for non-text content rather than rendering garbage.
Source
Thrown at yazi-core/src/highlighter.rs:73
syntaxes,
syntax: None,
})
}
pub fn abort() { INCR.next(); }
fn highlight(mut self) -> Result<Text<'static>, PeekError> {
self.load_syntax()?;
let mut plain = self.syntax.is_none();
let mut h = self.syntax.map(|syntax| HighlightLines::new(syntax, &self.theme));
let mut i = 0;
let mut buf = vec![];
let mut lines = Vec::with_capacity(self.size.height as usize);
let mut inspected = 0u16;
while self.reader.read_until(b'\n', &mut buf).is_ok_and(|n| n > 0) {
if Self::is_binary(&buf, &mut inspected) {
Err(anyhow!("Binary file"))?;
}
let remaining = Self::normalize_control_chars(&mut buf);
if remaining || buf.len() > 5000 {
plain = true;
}
self.ensure_not_cancelled()?;
if plain && !self.process_plain(&buf, &mut i, &mut lines)? {
break;
} else if !plain && !self.process_hyper(&buf, &mut i, &mut lines, h.as_mut())? {
break;
}
buf.clear();
}
if self.skip > 0 && i < self.skip + self.size.height as usize {
return Err(PeekError::Exceeded(i.saturating_sub(self.size.height as _)));View on GitHub (pinned to 94abcfa92f)
Solutions
- Treat it as expected signal: catch this PeekError and render the fallback (placeholder) preview
- Add a filetype rule in yazi.toml routing that extension/mime to an appropriate previewer
- For UTF-16 files, register an external previewer that transcodes, or convert the file
Example fix
// before
let text = highlighter.highlight().await?;
// after
let text = match highlighter.highlight().await {
Ok(t) => t,
Err(e) if e.to_string() == "Binary file" => return render_fallback(),
Err(e) => return Err(e),
}; Defensive patterns
Strategy: fallback
Validate before calling
// Cheap pre-check: sniff for NUL bytes before highlighting.
use std::io::Read;
let mut probe = [0; 4096];
let n = std::fs::File::open(&path)?.read(&mut probe)?;
if probe[..n].contains(&0) {
return render_fallback(); // skip the highlighter entirely
} Type guard
fn looks_binary(prefix: &[u8]) -> bool { prefix.contains(&0) } Try / catch
match highlighter.highlight().await {
Ok(t) => t,
Err(e) if e.to_string() == "Binary file" => render_fallback(),
Err(e) => return Err(e),
} Prevention
- Always pair the highlighter with a fallback renderer for this error
- Register filetype rules so binaries never reach the text previewer
- Expect UTF-16 content to trip the binary detector; give it a dedicated previewer
When it happens
Trigger: Previewing a file that reaches the text-preview path but contains binary bytes in its first lines: unrecognized binaries (no filetype rule matched), files with embedded NULs, or UTF-16 text whose NUL bytes trip the detector.
Common situations: Extensionless/misdetectced binaries falling through to text preview; UTF-16 files; plugins not registering a previewer for a custom binary mime type.
AI-assisted analysis of sxyazi/yazi@94abcfa92f (2026-08-16).
Data as JSON: /api/errors/eff6dc1621ce6d71.
Report an issue: GitHub.