{"record":{"id":"4dda6ed04bd9ca97","repo":"sxyazi/yazi","slug":"plugin-name-cannot-be-empty","errorCode":null,"errorMessage":"plugin name cannot be empty","messagePattern":"plugin name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"yazi-core/src/app/plugin.rs","lineNumber":33,"sourceCode":"\n#[derive(Clone, Debug, Default)]\npub struct PluginOpt {\n\tpub name:     SStr,\n\tpub args:     HashMap<DataKey, Data>,\n\tpub mode:     PluginMode,\n\tpub method:   PluginMethod,\n\tpub scope:    Scope,\n\tpub callback: Option<Box<dyn PluginCallback>>,\n}\n\nimpl_data_any!(PluginOpt);\n\nimpl TryFrom<ActionCow> for PluginOpt {\n\ttype Error = anyhow::Error;\n\n\tfn try_from(mut a: ActionCow) -> Result<Self, Self::Error> {\n\t\tlet Some(name) = a.take_first::<SStr>().ok().filter(|s| !s.is_empty()) else {\n\t\t\tbail!(\"plugin name cannot be empty\");\n\t\t};\n\n\t\tlet args = if let Ok(s) = a.second() {\n\t\t\tlet (words, last) = yazi_shared::shell::unix::split(s, true)?;\n\t\t\tCmd::parse_args(words, last)?\n\t\t} else {\n\t\t\ta.take_second().unwrap_or_default()\n\t\t};\n\n\t\tOk(Self {\n\t\t\tname: Self::normalize_name(name),\n\t\t\targs,\n\t\t\tmode: a.str(\"mode\").parse().unwrap_or_default(),\n\t\t\tmethod: a.str(\"method\").parse().unwrap_or_default(),\n\t\t\tscope: a.take_any(\"scope\").unwrap_or_default(),\n\t\t\tcallback: a.take_any(\"callback\"),\n\t\t})\n\t}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/sxyazi/yazi/blob/5f901b886b14de1f17460b6e52e9de5d67f8aba9/yazi-core/src/app/plugin.rs#L15-L51","documentation":"Converting an ActionCow into PluginOpt (yazi-core/src/app/plugin.rs:33) requires the action's first argument to be a non-empty plugin name. If the first argument is missing or empty, the conversion bails because a plugin invocation is meaningless without a name.","triggerScenarios":"Emitting or dispatching a `plugin` action whose first argument (`a.take_first::<SStr>()`) is absent or the empty string, e.g. `plugin ''` or an action built with no args.","commonSituations":"Keymap entries like `{ on = 'p', run = 'plugin' }` missing the plugin name, shell-style quoting errors that collapse the argument, or dynamic plugin names computed at runtime that end up empty.","solutions":["Add the plugin name as the first argument of the plugin action, e.g. `plugin my-plugin --args`.","Check keymap/config strings for missing or accidentally quoted-away plugin names.","In code, guard the plugin name variable for emptiness before dispatching the action."],"exampleFix":"// before\nrun = \"plugin\"\n// after\nrun = \"plugin smart-enter\"","handlingStrategy":"validation","validationCode":"let name = plugin_arg.trim();\nif name.is_empty() {\n    eprintln!(\"plugin action requires a non-empty name\");\n    return;\n}\n// now safe: app.plugin(format!(\"plugin {name}\"))","typeGuard":"fn valid_plugin_name(s: Option<&str>) -> bool {\n    s.map(|s| !s.is_empty()).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Always quote the plugin name in keymap run strings: `plugin my-plugin`.","Verify dynamic plugin names with a non-empty check before dispatching.","Prefer the `plugin` action form with the name as the first argument, args after `--`."],"tags":["plugin","action-parsing","argument-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"5f901b886b14de1f17460b6e52e9de5d67f8aba9","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}