sxyazi/yazi · error

Plugin name `{plugin}` must be in kebab-case

Error message

Plugin name `{plugin}` must be in kebab-case

What it means

Loader::explode_name_parts parses a plugin name like `plugin.entry` (with `.main` defaulting the entry) and validates that the plugin portion is kebab-case (lowercase words separated by hyphens). Plugin names become filesystem module paths and Lua identifiers, so naming must be normalized; anything else is rejected with this message.

Source

Thrown at yazi-runner/src/loader/loader.rs:192

	pub fn compatible_or_error(name: &str, chunk: &Chunk) -> Result<()> {
		if chunk.compatible() {
			return Ok(());
		}

		bail!(
			"Plugin `{name}` requires at least Yazi {}, but your current version is Yazi {}.",
			chunk.since,
			yazi_version::version_long()
		);
	}

	fn explode_name_parts(name: &str) -> anyhow::Result<(&str, &str, &str)> {
		let name = name.strip_suffix(".main").unwrap_or(name);
		let (plugin, entry) =
			if let Some((a, b)) = name.split_once(".") { (a, b) } else { (name, "main") };

		ensure!(plugin.as_bytes().kebab_cased(), "Plugin name `{plugin}` must be in kebab-case");
		ensure!(entry.as_bytes().kebab_cased(), "Entry name `{entry}` must be in kebab-case");
		Ok((name, plugin, entry))
	}
}

View on GitHub (pinned to 8ebf930f17)

Solutions

  1. Rename the plugin directory/config entry to kebab-case (e.g., MyPlugin -> my-plugin)
  2. If invoking by name, correct the string to the plugin's kebab-case name
  3. Check for underscores vs hyphens in the name

Example fix

// before
ya.plugin("MyPlugin.main")
// after
ya.plugin("my-plugin.main")
Defensive patterns

Strategy: validation

Validate before calling

fn is_kebab(s: &str) -> bool {
    !s.is_empty()
        && s.bytes().all(|b| b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'-')
        && !s.starts_with('-') && !s.ends_with('-')
}
assert!(is_kebab("my-plugin"));

Type guard

fn valid_plugin_name(name: &str) -> Option<(&str, &str)> {
    let (p, e) = name.split_once('.').unwrap_or((name, "main"));
    is_kebab(p).then_some((p, e))
}

Try / catch

match Loader::load(name) {
    Ok(p) => p,
    Err(e) => eprintln!("plugin load failed: {e}") // message names the offending `plugin`
}

Prevention

When it happens

Trigger: Loading or resolving a plugin whose name segment before the first dot (or whole name when no dot) is not kebab-case, e.g. `MyPlugin`, `my_plugin`, `myPlugin.main`, or containing uppercase/underscores/spaces.

Common situations: Typos in a plugin name passed to plugin loader calls, referencing a plugin directory created with CamelCase or snake_case naming, or installing a third-party plugin whose directory name violates the convention.

Related errors


AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-02). Data as JSON: /api/errors/aed8472c1c197e35. Report an issue: GitHub.