sxyazi/yazi · error · anyhow::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

Thrown by TryFrom<Data> for File (yazi-fs/src/file/data.rs:13) when Data::into_any::<File>() fails: the Data value is not the Data::Any box holding a File. The File type crosses the event/Lua boundary only as an opaque Any payload, so any other variant (Integer, String, Table, List, or an Any of a different type such as Files or Folder) produces this error. The owned flavor applies when the Data is consumed by value.

Source

Thrown at yazi-actor/src/mgr/escape.rs:84

	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 441b332de8)

Solutions

  1. Pass an actual File object obtained from the yazi API (hovered entry, tab file) rather than a URL, table, or list
  2. For multiple files use the Files-typed parameter, not File
  3. Verify with ya.dbg()/type() on the Lua side that the value is a File userdata before emitting
  4. Check the receiving form expects the type you send; rename/retarget the argument if they diverged after an upgrade

Example fix

-- before
ya.emit("some_cmd", { file = "/tmp/a.txt" })  -- a string, not a File
-- after
ya.emit("some_cmd", { file = hovered })  -- File userdata from the API
Defensive patterns

Strategy: type-guard

Validate before calling

-- Lua: verify the value is File userdata before emitting
if type(entry) == "userdata" or (type(entry) == "table" and getmetatable(entry) and getmetatable(entry).__name == "File") then
  ya.emit("cmd", { file = entry })
end

Type guard

-- Lua
local function is_file(v)
  return type(v) == "userdata" or type(v) == "table"
end -- strongest check: obtain v only from yazi's hovered/entry APIs

Try / catch

-- Lua
local ok, err = pcall(ya.emit, "cmd", { file = v })
if not ok then ya.dbg("expected a File: " .. tostring(err)) end

Prevention

When it happens

Trigger: Calling an API that does `Data -> File` conversion (e.g. a form taking a File argument) while the sender passed a plain value, a different Any type, or a list of files (which converts to Files, not File); mixing up hovered-file and selected-files arguments in plugin calls.

Common situations: Plugin code passing `cx.tab.current.hovered`-style tables or URLs where a File object is required; passing the result of a files-collection API to a single-File parameter; version changes moving a field from File to another type.

Related errors


AI-assisted analysis of sxyazi/yazi@441b332de8 (2026-08-19). Data as JSON: /api/errors/a6ab13e9b38444af. Report an issue: GitHub.