{"record":{"id":"15ba7db65a8f8a73","repo":"sxyazi/yazi","slug":"invalid-trash-info-header","errorCode":null,"errorMessage":"invalid trash info header","messagePattern":"invalid trash info header","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-fs/src/trash/freedesktop/trash_info.rs","lineNumber":49,"sourceCode":"\t\t\t.file_stem()\n\t\t\t.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, \"invalid trash info path\"))?;\n\n\t\tlet original = Self::parse_original(info, root)?;\n\t\tif original.file_name().is_none() {\n\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidData, \"invalid original trash path\"));\n\t\t}\n\n\t\tOk(Self { root: root.to_owned(), backing: root.join(\"files\").join(stem), original })\n\t}\n\n\tfn parse_original(info: &Path, root: &Path) -> io::Result<PathBuf> {\n\t\tlet mut reader = BufReader::new(File::open(info)?);\n\t\tlet mut line = Vec::new();\n\n\t\treader.read_until(b'\\n', &mut line)?;\n\t\tSelf::trim_line(&mut line);\n\t\tif line != b\"[Trash Info]\" {\n\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidData, \"invalid trash info header\"));\n\t\t}\n\n\t\tloop {\n\t\t\tline.clear();\n\t\t\tif reader.read_until(b'\\n', &mut line)? == 0 {\n\t\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidData, \"trash info has no Path\"));\n\t\t\t}\n\n\t\t\tSelf::trim_line(&mut line);\n\t\t\tlet Some(value) = line.strip_prefix(b\"Path=\") else { continue };\n\t\t\tlet decoded: Cow<[u8]> = percent_decode(value).into();\n\n\t\t\tlet path = Path::new(OsStr::from_bytes(decoded.as_ref()));\n\t\t\tif path.as_os_str().is_empty() || !path.is_absolute() && path.has_parent_component() {\n\t\t\t\treturn Err(io::Error::new(io::ErrorKind::InvalidData, \"invalid original trash path\"));\n\t\t\t}\n\n\t\t\treturn Ok(if path.is_absolute() {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/sxyazi/yazi/blob/94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2/yazi-fs/src/trash/freedesktop/trash_info.rs#L31-L67","documentation":"`TrashInfo::parse_original` (trash_info.rs:49) reads the first line of the `.trashinfo` file and requires it to be exactly `[Trash Info]` (after trimming trailing CR/LF). Any other first line — a different header, a BOM, garbage bytes — yields `ErrorKind::InvalidData`, `invalid trash info header`.","triggerScenarios":"Opening (via `Trash::entry`) a `.trashinfo` whose first line is not the INI section header: text editors saving with a UTF-8 BOM, files truncated at the top, or non-trash files merely named `*.trashinfo`.","commonSituations":"Hand-edited metadata saved by editors that add BOMs or re-encode; partially overwritten files after a crash; a random file renamed to `.trashinfo`.","solutions":["Fix the file: make line 1 exactly `[Trash Info]`, with no leading BOM or whitespace.","If the file is junk, delete it together with its backing entry in `files/`.","Regenerate the `.trashinfo` with correct `Path=`/`DeletionDate=` if you know the original location."],"exampleFix":"# before (hex: EF BB BF 5B ... = BOM before header)\n﻿[Trash Info]\nPath=/home/alice/cat.jpg\n\n# after\n[Trash Info]\nPath=/home/alice/cat.jpg","handlingStrategy":"try-catch","validationCode":"// quick pre-check when operating on .trashinfo files directly:\nfn has_valid_header(p: &std::path::Path) -> std::io::Result<bool> {\n    use std::io::BufRead;\n    let mut line = Vec::new();\n    std::io::BufReader::new(std::fs::File::open(p)?).read_until(b'\\n', &mut line)?;\n    while matches!(line.last(), Some(b'\\n' | b'\\r')) { line.pop(); }\n    Ok(line == b\"[Trash Info]\")\n}","typeGuard":null,"tryCatchPattern":"match trash.entry(&id) {\n    Ok(e) => { /* ... */ }\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => {\n        // header corrupted: rewrite line 1 as exactly \"[Trash Info]\" (no BOM), or delete the file\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Save .trashinfo files as plain ASCII/UTF-8 without BOM.","Keep line 1 exactly `[Trash Info]` when editing metadata.","Treat InvalidData from entry() as on-disk corruption; repair or purge, don't retry blindly."],"tags":["trash","trashinfo","header","corruption","invalid-data"],"backgroundTag":null,"analyzedSha":"94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2","analyzedAt":"2026-08-16T09:56:24.836Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}