{"record":{"id":"eff6dc1621ce6d71","repo":"sxyazi/yazi","slug":"binary-file","errorCode":null,"errorMessage":"Binary file","messagePattern":"Binary file","errorType":"exception","errorClass":"PeekError::Unexpected","httpStatus":null,"severity":"info","filePath":"yazi-core/src/highlighter.rs","lineNumber":73,"sourceCode":"\t\t\tsyntaxes,\n\t\t\tsyntax: None,\n\t\t})\n\t}\n\n\tpub fn abort() { INCR.next(); }\n\n\tfn highlight(mut self) -> Result<Text<'static>, PeekError> {\n\t\tself.load_syntax()?;\n\t\tlet mut plain = self.syntax.is_none();\n\t\tlet mut h = self.syntax.map(|syntax| HighlightLines::new(syntax, &self.theme));\n\n\t\tlet mut i = 0;\n\t\tlet mut buf = vec![];\n\t\tlet mut lines = Vec::with_capacity(self.size.height as usize);\n\t\tlet mut inspected = 0u16;\n\t\twhile self.reader.read_until(b'\\n', &mut buf).is_ok_and(|n| n > 0) {\n\t\t\tif Self::is_binary(&buf, &mut inspected) {\n\t\t\t\tErr(anyhow!(\"Binary file\"))?;\n\t\t\t}\n\n\t\t\tlet remaining = Self::normalize_control_chars(&mut buf);\n\t\t\tif remaining || buf.len() > 5000 {\n\t\t\t\tplain = true;\n\t\t\t}\n\n\t\t\tself.ensure_not_cancelled()?;\n\t\t\tif plain && !self.process_plain(&buf, &mut i, &mut lines)? {\n\t\t\t\tbreak;\n\t\t\t} else if !plain && !self.process_hyper(&buf, &mut i, &mut lines, h.as_mut())? {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbuf.clear();\n\t\t}\n\n\t\tif self.skip > 0 && i < self.skip + self.size.height as usize {\n\t\t\treturn Err(PeekError::Exceeded(i.saturating_sub(self.size.height as _)));","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/sxyazi/yazi/blob/94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2/yazi-core/src/highlighter.rs#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"Extensionless/misdetectced binaries falling through to text preview; UTF-16 files; plugins not registering a previewer for a custom binary mime type.","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"],"exampleFix":"// before\nlet text = highlighter.highlight().await?;\n\n// after\nlet text = match highlighter.highlight().await {\n    Ok(t) => t,\n    Err(e) if e.to_string() == \"Binary file\" => return render_fallback(),\n    Err(e) => return Err(e),\n};","handlingStrategy":"fallback","validationCode":"// Cheap pre-check: sniff for NUL bytes before highlighting.\nuse std::io::Read;\nlet mut probe = [0; 4096];\nlet n = std::fs::File::open(&path)?.read(&mut probe)?;\nif probe[..n].contains(&0) {\n    return render_fallback(); // skip the highlighter entirely\n}","typeGuard":"fn looks_binary(prefix: &[u8]) -> bool { prefix.contains(&0) }","tryCatchPattern":"match highlighter.highlight().await {\n    Ok(t) => t,\n    Err(e) if e.to_string() == \"Binary file\" => render_fallback(),\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["preview","highlighter","binary","peek"],"backgroundTag":null,"analyzedSha":"94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2","analyzedAt":"2026-08-16T09:56:24.836Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}