sxyazi/yazi · error
Some files cannot be selected, due to path nesting conflict.
Error message
Some files cannot be selected, due to path nesting conflict.
What it means
When escaping visual mode with selection, yazi tries to add all visual-mode files to the tab's persistent selection via `add_many`. The selection set rejects entries whose paths are nested inside another selected entry (a file inside an already-selected directory would be selected twice). If some entries could not be added, the actor warns and bails instead of silently producing an inconsistent selection.
Solutions
- Flatten the selection before exiting visual mode: keep only top-most entries (drop children of already-selected directories)
- Handle the bail in your keymap/plugin and notify the user to review the selection
- Modify the selection incrementally with `add` checks or pre-filter nested paths before calling the actor
Example fix
// before
let files = dir_and_children; // contains parent + nested children
act!(mgr:escape_visual, cx, (true, files))?;
// after
let files: Vec<_> = dir_and_children.into_iter()
.filter(|f| !dir_and_children.iter().any(|o| o.url != f.url && f.url.starts_with(&o.url)))
.collect();
act!(mgr:escape_visual, cx, (true, files))?; Defensive patterns
Strategy: try-catch
Validate before calling
fn has_nested_conflict(files: &[File]) -> bool {
files.iter().any(|f| files.iter().any(|o| {
o.url != f.url && f.url.starts_with(&o.url)
}))
} Type guard
fn is_safe_selection(files: &[File]) -> bool {
!has_nested_conflict(files)
} Try / catch
match escape_visual(cx, files).await {
Err(e) if e.to_string().contains("path nesting conflict") => {
notify::warn("Selection contains a directory and its children; deselect one");
}
other => other?,
} Prevention
- Deselect children when a parent directory is selected
- Pre-filter nested entries before bulk selection calls
- Show the selection list to users before exiting visual mode in scripted flows
When it happens
Trigger: Pressing the escape/visual-exit key that runs this actor while the visual selection contains both a directory and files (or subdirectories) nested inside it, so `Selected::add_many` returns a count smaller than `files.len()`.
Common situations: User selects a parent directory, then moves the cursor into it and selects children in visual mode, then exits visual mode expecting everything to stay selected; bulk-selection plugins that gather recursive file lists including ancestors.
Related errors
- Cannot create file at root
- Failed to join new name with parent directory
- Invalid 'lock' in UpdatePeekedForm
- Invalid 'lock' in UpdateSpottedForm
- Invalid 'opt' in DisplaceDoForm
AI-assisted analysis of sxyazi/yazi@a541adde4e (2026-09-02).
Data as JSON: /api/errors/a6ab13e9b38444af.
Report an issue: GitHub.
Appendix: source
Thrown at yazi-actor/src/mgr/escape.rs:85
fn act(cx: &mut Ctx, _: Self::Form) -> Result<Data> {
let tab = cx.tab_mut();
let select = tab.mode.is_select();
let Some(indices) = tab.mode.take_visual(tab.current.cursor, tab.current.entries.len()) else {
succ!(false)
};
render!();
let files: Vec<_> = indices.into_iter().filter_map(|i| tab.current.entries.get(i)).collect();
if !select {
tab.selected.remove_many(files);
} else if files.len() != tab.selected.add_many(files) {
NotifyProxy::push_warn(
"Escape visual mode",
"Some files cannot be selected, due to path nesting conflict.",
);
bail!("Some files cannot be selected, due to path nesting conflict.");
}
succ!(true)
}
}
// --- Filter
pub struct EscapeFilter;
impl Actor for EscapeFilter {
type Form = VoidForm;
const NAME: &str = "escape_filter";
fn act(cx: &mut Ctx, _: Self::Form) -> Result<Data> {
if cx.current_mut().entries.filter().is_none() {
succ!(false);
}View on GitHub (pinned to a541adde4e)