sxyazi/yazi · error

Unwinding must be enabled for Windows. Please use `cargo bui

Error message

Unwinding must be enabled for Windows. Please use `cargo build --profile release-windows --locked` instead to build Yazi.

What it means

Thrown by the impl_into_number! macro in yazi-shared (yazi-shared/src/data/macros.rs:72) when converting a Data value to a numeric type whose conversion is lossy or of an unaccepted variant. The match arms carry round-trip guards: an Integer must satisfy `*i == *i as $b as i64`, a float must survive `f64::from(*n) == f64::from(*n) as $b as f64`, and an Id must fit the target; otherwise control falls to the bail. Non-numeric variants (Bool, Nil, List, Table) also land here.

Source

Thrown at yazi-fm/build.rs:13

use std::{env, error::Error};

fn main() -> Result<(), Box<dyn Error>> {
	let dir = env::var("OUT_DIR").unwrap();

	// cargo build
	//   C:\Users\Ika\Desktop\yazi\target\release\build\yazi-fm-cfc94820f71daa30\out
	// cargo install
	//   C:\Users\Ika\AppData\Local\Temp\cargo-installTFU8cj\release\build\
	// yazi-fm-45dffef2500eecd0\out

	if dir.contains(r"\release\build\yazi-fm-") {
		panic!(
			"Unwinding must be enabled for Windows. Please use `cargo build --profile release-windows --locked` instead to build Yazi."
		);
	}

	let manifest = env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy().replace(r"\", "/");
	if manifest.contains("/git/checkouts/yazi-")
		|| manifest.contains("/registry/src/index.crates.io-")
	{
		panic!(
			"Due to Cargo's limitations, Yazi on crates.io must be built with `cargo install --force yazi-build`"
		);
	}

	Ok(())
}

View on GitHub (pinned to 441b332de8)

Solutions

  1. Clamp or validate the value on the Lua side before emitting so it fits the Rust field's range
  2. Check for nil/boolean and convert explicitly with tonumber() before passing
  3. Log the delivered Data (YAZI_LOG=debug / ya.dbg) to identify which argument is out of range
  4. If the field should accept the value, widen the Rust field type in the receiving form

Example fix

-- before
ya.emit("preview", { ratio = 400 })  -- handler expects u8
-- after
ya.emit("preview", { ratio = math.min(400, 255) })
Defensive patterns

Strategy: validation

Validate before calling

-- Lua: range-check before emitting
local function clamp_u8(v) return math.max(0, math.min(255, math.floor(tonumber(v) or 0))) end

Type guard

-- Lua
local function is_number(v)
  local n = tonumber(v)
  return n ~= nil and n == n and n ~= math.huge and n ~= -math.huge
end

Try / catch

local ok, err = pcall(ya.emit, "cmd", { ratio = v })
if not ok then ya.dbg("numeric arg rejected: " .. tostring(err)) end

Prevention

When it happens

Trigger: Passing a number that does not fit the target type (e.g. 300 or -1 to a u8-typed argument, a fractional value to an integer field with a lossy cast, NaN/Infinity); passing nil/boolean/table where the handler does get::<f64>/take::<u32>; an Id (u64) exceeding the target's range for signed targets.

Common situations: Config/plugin values out of range after a version change narrowed a field type; Lua integers exceeding 2^53 losing precision through f64; negative values sent to unsigned fields.

Related errors


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