{"record":{"id":"09d90e186f239ee5","repo":"sxyazi/yazi","slug":"invalid-trash-mount-point","errorCode":null,"errorMessage":"invalid trash mount point","messagePattern":"invalid trash mount point","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"yazi-fs/src/trash/freedesktop/trash_info.rs","lineNumber":88,"sourceCode":"\t\t\t\tSelf::mount_point(root)?.join(path)\n\t\t\t});\n\t\t}\n\t}\n\n\t// /mnt/disk/.Trash/1000           =>  /mnt/disk\n\t// /home/alice/.local/share/Trash  =>  /home/alice/.local/share\n\tfn mount_point(root: &Path) -> io::Result<&Path> {\n\t\tlet uid = USERS_CACHE.get_current_uid().to_string();\n\n\t\tif root.file_name() == Some(OsStr::new(&uid))\n\t\t\t&& let Some(parent) = root.parent()\n\t\t\t&& parent.file_name() == Some(OsStr::new(\".Trash\"))\n\t\t{\n\t\t\tparent.parent()\n\t\t} else {\n\t\t\troot.parent()\n\t\t}\n\t\t.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, \"invalid trash mount point\"))\n\t}\n\n\tfn trim_line(line: &mut Vec<u8>) {\n\t\twhile matches!(line.last(), Some(b'\\n' | b'\\r')) {\n\t\t\tline.pop();\n\t\t}\n\t}\n}\n","sourceCodeStart":70,"sourceCodeEnd":97,"githubUrl":"https://github.com/sxyazi/yazi/blob/94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2/yazi-fs/src/trash/freedesktop/trash_info.rs#L70-L97","documentation":"`TrashInfo::mount_point` (trash_info.rs:88) computes the mount point that relative `Path=` values resolve against: for a top-level trash `<mp>/.Trash/<uid>` it strips both segments, otherwise it takes the parent of `<mp>/Trash`. If the computed ancestor does not exist (e.g. the trash root is `/` so it has no parent), it returns `ErrorKind::InvalidData`, `invalid trash mount point`.","triggerScenarios":"A `.trashinfo` whose `Path=` is relative (forcing mount-point resolution) while its trash root is at or effectively at the filesystem root, leaving no parent to return.","commonSituations":"Trash directories created at `/` or under paths with deleted/moved parents; exotic layouts where `root.parent()` is None; essentially only reachable with malformed on-disk state.","solutions":["Fix the `Path=` in the `.trashinfo` to an absolute path so mount-point resolution is skipped entirely.","Relocate the trash to a standard location (`$XDG_DATA_HOME/Trash` or `<mount>/.Trash/$uid`) so a parent exists.","Delete the degenerate trash metadata if the item is not worth salvaging."],"exampleFix":"# before: relative Path forces mount_point() on a root-level trash\n[Trash Info]\nPath=report.pdf\n\n# after\n[Trash Info]\nPath=/home/alice/report.pdf","handlingStrategy":"try-catch","validationCode":"// only relevant when Path= is relative: ensure the trash root has a parent\nif !path.is_absolute() && root.parent().is_none() {\n    // mount point cannot be derived; rewrite Path= as absolute instead\n}","typeGuard":null,"tryCatchPattern":"match trash.entry(&id) {\n    Ok(e) => { /* ... */ }\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => {\n        // undecodable mount point: make Path= absolute so mount_point() is never called\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Prefer absolute Path= values; relative values depend on trash-root layout staying sane.","Keep trash dirs in standard locations ($XDG_DATA_HOME/Trash, <mount>/.Trash/$uid).","Never create a Trash directory at the filesystem root."],"tags":["trash","trashinfo","mount-point","invalid-data"],"backgroundTag":null,"analyzedSha":"94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2","analyzedAt":"2026-08-16T09:56:24.836Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}