sxyazi/yazi · error

Invalid 'lock' in UpdatePeekedForm

Error message

Invalid 'lock' in UpdatePeekedForm

What it means

UpdatePeekedForm delivers the result of a peek job back to the manager: it requires a 'lock' entry (the peek identity/token) and an optional 'scope'. The 'lock' is mandatory — a.take_any("lock") returning None raises "Invalid 'lock' in UpdatePeekedForm". Without the lock the manager cannot correlate the update with the pending peek, so the message is rejected.

Solutions

  1. Attach the original peek lock (obtained when initiating peek/peek jobs) under key 'lock'.
  2. Ensure the lock type matches the current UpdatePeekedForm definition in your yazi version.
  3. Emit peek updates via yazi's internal job completion path rather than constructing the action manually.
  4. Optionally also set 'scope'; it defaults via unwrap_or_default, but the lock itself has no default.

Example fix

// before
let a = ActionCow::from("mgr.update-peeked"); // no lock
// after
let a = ActionCow::from(("mgr.update-peeked", (lock, scope)));
// 'lock' must be the PeekLock captured when the peek started
Defensive patterns

Strategy: validation

Validate before calling

if !action.has("lock") {
    anyhow::bail!("update-peeked requires the peek 'lock'");
}
let form = UpdatePeekedForm::try_from(action)?;

Type guard

fn has_lock(a: &ActionCow) -> bool { a.has("lock") }

Try / catch

let form = UpdatePeekedForm::try_from(action)
    .context("peek update missing lock; drop stale update")?; // safe to ignore

Prevention

When it happens

Trigger: Dispatching mgr.update-peeked without a 'lock' payload, or with a lock value of a type that cannot be taken as the expected PeekLock/target type.

Common situations: Plugin or third-party code faking a peek-update message; a yazi version change altering the lock representation so old emitters attach the wrong type; dropping fields when cloning/forwarding the action.

Related errors


AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02). Data as JSON: /api/errors/367b6ce3237ff7fe. Report an issue: GitHub.

Appendix: source

Thrown at yazi-parser/src/mgr/update_peeked.rs:18

use anyhow::anyhow;
use mlua::{ExternalError, FromLua, IntoLua, Lua, Value};
use yazi_binding::Scope;
use yazi_core::tab::PreviewLock;
use yazi_shared::event::ActionCow;

#[derive(Clone, Debug)]
pub struct UpdatePeekedForm {
	pub lock:  PreviewLock,
	pub scope: Scope,
}

impl TryFrom<ActionCow> for UpdatePeekedForm {
	type Error = anyhow::Error;

	fn try_from(mut a: ActionCow) -> Result<Self, Self::Error> {
		Ok(Self {
			lock:  a.take_any("lock").ok_or_else(|| anyhow!("Invalid 'lock' in UpdatePeekedForm"))?,
			scope: a.take_any("scope").unwrap_or_default(),
		})
	}
}

impl FromLua for UpdatePeekedForm {
	fn from_lua(_: Value, _: &Lua) -> mlua::Result<Self> { Err("unsupported".into_lua_err()) }
}

impl IntoLua for UpdatePeekedForm {
	fn into_lua(self, _: &Lua) -> mlua::Result<Value> { Err("unsupported".into_lua_err()) }
}

View on GitHub (pinned to 5f901b886b)